【问题标题】:awk command inside while loop creates empty output fileswhile 循环中的 awk 命令创建空的输出文件
【发布时间】:2014-12-21 17:46:45
【问题描述】:

我正在尝试遍历文件 (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 命令来查找单个表达式时,它工作得很好......

感谢您的帮助!

【问题讨论】:

    标签: bash awk while-loop


    【解决方案1】:

    替换:

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

    与:

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

    问题在于line 是一个shell 变量。顶行在 single-引号内有$line。外壳不会触及单引号内的任何内容。因此,print 语句仅在行匹配文字美元符号后跟 line 时才会执行。

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

    另一种方法,可能很危险

    我们可以尝试直接使用shell变量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第一列 匹配。如果是这种情况,您可能希望通过以下方式优化条件以避免错误匹配:

    awk -v line="$line" '$1 ~ line' Data.txt
    

    【讨论】:

    • 完美运行!我明白为什么错了,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 2020-01-23
    • 2018-06-12
    • 2018-03-20
    • 2012-01-02
    相关资源
    最近更新 更多