bash与awk交互报错:无法打开文件'c',求问题排查
你的awk脚本和调用方式的核心错误解析
1. Bash变量未加引号导致参数分裂
你的bash脚本中,-v input=${string}没有给${string}添加双引号,而string是多行字符串$'a\nb\nc\nd\ne',bash会将其展开为空格分隔的多个参数:a、b、c、d、e。这使得你的awk命令实际被解析为:
awk -v input=a b c d e -f post.awk < file_input.txt > file_output.txt
awk会把b、c、d、e当作需要处理的输入文件,因此尝试打开文件c时触发报错。
2. 混淆Bash位置变量与Awk字段变量
你误以为awk中的$1、$3对应bash命令行的位置参数,这是完全错误的:
- Bash的
$1、$3是脚本/命令的命令行参数,而awk里的$1、$3是当前处理行的第1、第3个字段,二者没有关联。 - 通过
-v var=value传入awk的变量,直接用变量名input访问即可,并非$1。
3. 误解重定向的作用范围
你使用的< file_input.txt和> file_output.txt是Bash层面的重定向,不是传给awk的参数:
< file_input.txt是让awk的标准输入来自该文件,awk不会将其视为命令行参数,因此无法通过变量获取这个文件名。> file_output.txt是让awk的标准输出写入该文件,无需在awk脚本中再用> $3重复处理。
修正后的脚本示例
修正的Bash脚本
#!/bin/bash string=$'a\nb\nc\nd\ne' echo "$string" # 给变量加双引号避免参数分裂,输出重定向交由bash处理 awk -v input="$string" -f post.awk < file_input.txt > file_output.txt
修正的Awk脚本
#!/bin/gawk BEGIN { # 从标准输入(即file_input.txt)读取一行 getline tmp # 直接打印,输出会被bash的重定向写入目标文件 print tmp } END { # 打印传入的input变量内容 print input }
额外说明:如果需要在awk内指定输出文件
若要在awk脚本中直接控制输出文件,可将文件名作为变量传入:
awk -v input="$string" -v outfile="file_output.txt" -f post.awk file_input.txt
对应的awk脚本:
#!/bin/gawk BEGIN { # 从第一个输入文件(file_input.txt)读取一行 getline tmp < ARGV[1] print tmp > outfile } END { print input > outfile }
这里ARGV是awk内置数组,存储命令行传入的所有非选项参数,ARGV[1]即为file_input.txt。
内容的提问来源于stack exchange,提问作者Vinod
相关产品推荐
相关产品推荐

