如何在AWK脚本内部调用CSV文件,无需在终端指定文件名
在AWK脚本中直接指定CSV文件,无需终端传入文件名
我明白你想让AWK脚本直接读取file.csv,不用每次在终端里输入文件名作为参数。你之前的两种写法都有小问题,我来帮你修正:
首先说你尝试的getline写法问题:你没给文件名加引号,AWK会把file.csv当成一个变量而不是文件名,所以找不到文件;另外多个BEGIN块可以合并成一个,逻辑更清晰。
下面给你两种可行的解决方案:
方法一:直接在脚本末尾指定文件名(推荐)
这是最符合AWK设计的写法,脚本会自动读取指定的文件,不用手动处理文件IO:
#!/usr/bin/awk -f BEGIN { print "Filtered Elements:" FS = "," # 把多个BEGIN块合并成一个,更清晰 } { # 把三个if判断放在同一个主处理块里,避免重复遍历每行 if ($8~/.*5.*/ && $2~/.*Sh.*/ && ($3~/.*i.*/ || $4~/.*s.*/)) { print } if ($3~/.*ra.*/ && $7~/.*18.*/ && $13~/.*r.*/) { print } if ($5~/.*7.*/ && $2~/.*l.*/ && ($4~/.*Fi.*/ || $12~/20.*/)) { print } } file.csv # 在这里指定要读取的文件,AWK会自动处理
这样你直接运行./script.awk就可以了,AWK会自动加载file.csv并执行你的过滤逻辑。
方法二:用getline手动读取文件
如果你一定要用getline的方式,需要修正文件名的引号和循环逻辑:
#!/usr/bin/awk -f BEGIN { print "Filtered Elements:" FS = "," # 文件名必须加双引号,告诉AWK这是字符串 while ((getline < "file.csv") > 0) { if ($8~/.*5.*/ && $2~/.*Sh.*/ && ($3~/.*i.*/ || $4~/.*s.*/)) { print } if ($3~/.*ra.*/ && $7~/.*18.*/ && $13~/.*r.*/) { print } if ($5~/.*7.*/ && $2~/.*l.*/ && ($4~/.*Fi.*/ || $12~/20.*/)) { print } } close("file.csv") # 读取完成后记得关闭文件,避免资源泄漏 }
为什么你之前的写法出错?
- 文件名未加引号:
file.csv没有被当作字符串,AWK会尝试查找名为file.csv的变量,而不是实际的文件 - 多个
BEGIN块虽然AWK会合并,但分开写容易混乱,合并成一个更易维护 getline的条件写法有误,正确的判断应该是(getline < "文件名") > 0,用来检查是否成功读取到行
两种方法都能实现你的需求,个人推荐第一种,因为更简洁,也符合AWK的常规使用方式。
内容的提问来源于stack exchange,提问作者Ignacio Such
相关产品推荐
相关产品推荐

