awk命令内部while循环创建空输出文件

时间:2014-10-26 11:29:38

标签: bash awk while-loop

我试图遍历文件行(Names.txt)并在另一个文件(Data.txt)上查找每行的表达式。我想在文件line.txt上打印包含一个表达式的Data.txt行。说我的文件Names.txt看起来像这样:

A
B
C
D

我的文件Data.txt看起来像这样:

A    info1
D    info2
C    info3
B    info4
E    info5
F    info6

我直接在终端(Mac OSX)上使用了以下命令:

while read line; do awk '/$line/ { print $0 }' Data.txt > $line.txt; done < Names.txt

尽管创建了所有文件$ line.txt,但遗憾的是它们都是空的。我使用while循环似乎是一个错误,因为当我只使用awk命令寻找单个表达式时它工作得很好......

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

替换:

awk '/$line/ { print $0 }' Data.txt

使用:

awk -v line="$line" '$0 ~ line { print $0 }' Data.txt

问题是line是一个shell变量。顶行在 - 引号内有$line。 shell不会触及单引号内的任何内容。因此,仅当行与printlin后面的文字符号匹配时,才会执行e语句。

在上面的第二个版本中,-v选项用于创建名为awk的{​​{1}}变量。然后可以在脚本中使用line变量。

另一种方法,可能是危险的

我们可以尝试直接使用shell变量awk,将其放在双引号中:

line

除非您信任awk "/$line/"' { print $0 }' Data.txt 的内容,否则请勿这样做。例如,如果line具有以下值:

line

然后,line='./ {print "Ha Ha"} /A' 脚本会毫无错误地执行,但它会做一些意想不到的事情。因为这可能是一个安全问题,所以使用上述awk变量方法会更安全。

有点隐秘的简化

如果awk命令有条件但没有操作,则默认值为awk。这意味着,如果您愿意,可以将print $0命令简化为:

awk

建议

您希望将awk -v line="$line" '$0 ~ line' Data.txt 中的行与Names.txt第一列相匹配。如果是这种情况,您可能希望通过使用:

来优化条件以避免错误匹配
Data.txt