使用包含 {BEGIN FS = "|"} 的命令 awk 匹配 2 个单独文件中的字段返回空行的输出

使用包含 {BEGIN FS = "|"} 的命令 awk 匹配 2 个单独文件中的字段返回空行的输出

两个文件:data1

    Name       |formula           |no. |dose|days|cost  |msg|em|notes
    Fname-Lname|BXXXT+GG          |8262|4   |14  |57.78 |   |  |sq
    Fname-Lname|SJXXT+GG          |8263|4¾  |14  |105.15|   |  |IB
    Fname-Lname|FJDHT+BH,LG,CQC,ZX|8264|5¾  |14  |46.20 |   |  |IB

数据2

10/12/2020|more-data-3456|105.15
10/12/2020|more-data-3456|95.10
11/12/2020|more.data-3456|30.30
14/12/2020|more-data-3456|45.55

我正在使用代码片段

awk 'BEGIN {FS = "|" } NR==FNR{a[$6];next} $3 in a {print $0}' data1 data2

匹配文件 data1 的 $6 中的值也出现在文件 data2 的 $3 中的位置。如果存在匹配,则打印出包含文件 data2 中的匹配的整个记录​​ ($0)。我期待:

10/12/2020|more-data-3456|105.15

但我只得到一个空行的输出。我"|"使用替换命令删除了文件分隔符," "命令代码完全按照预期工作,但确实希望|尽可能保留字段分隔符。我想了解为什么添加 BEGIN 块会导致这种情况。它是否导致 awk 加载空数组而不是从 S6 获取数据?我的 awk 水平仅高于初学者。编辑:我还使用了 -F 参数,得到了相同的结果,即输出一个空行。我正在使用 gawk 。

答案1

  1. 您可能有 DOS 行结尾,请参阅为什么我的工具输出会覆盖自身以及如何修复它,所以删除它(如果存在)(我将在下面的脚本中删除它和任何其他尾随空格sub())。
  2. 如果你得到一个空行输出,那么你的每个输入文件中都有空行,但我敢打赌你并没有真正得到一个空行输出,而是你得到了你应该得到的 1 行输出105.15CR最后会覆盖回行的开头 - 将输出通过管道传递到以| cat -v查看是否属实。
  3. 您的输入在某些地方的 s 前后有空格,|因此您应该设置FS为匹配 -FS=" *[|] *"
  4. 您不需要编写,{print $0}因为这是默认行为

尝试这个:

awk 'BEGIN{FS=" *[|] *"} {sub(/[[:space:]]+$/,"")} NR==FNR{a[$6];next} $3 in a' data1 data2

答案2

您的代码对我来说按原样工作,无论是在 GNU awk 5.1.0 上还是在 macOS awk 20200816 上。

您使用的是哪个版本的 awk?

请注意,您还可以使用命令行参数设置字段分隔符-F;如果你这样做了,那么这个BEGIN块就没有必要了。

相关内容