【问题标题】:How to make a strict match with awk如何与awk进行严格匹配
【发布时间】:2022-01-30 11:37:59
【问题描述】:

我正在用另一个文件查询一个文件,它们如下所示:

文件1:

Angela S Darvill| text text text text   
Helen Stanley| text text text text   
Carol Haigh S|text text text text .....

文件2:

Carol Haigh  
Helen Stanley  
Angela Darvill

这个命令:

awk 'NR==FNR{_[$1];next} ($1 in _)' File2.txt File1.txt

返回重叠的行,但没有严格匹配。严格匹配,应该只有 Helen Stanley 被退回。

如何在严格重叠时限制 awk?

【问题讨论】:

  • 不要使用_ 作为变量名——这比单字母变量名更难读,而且没有理由不至少想出一个字母,即使在这种情况下,“数组”只是a

标签: linux unix awk


【解决方案1】:

使用您展示的示例,请尝试以下操作。你在正确的轨道上,你需要做两件事,第一件事:在读取 file2.txt 时将整行作为数组 a 中的索引,并在 awk 开始读取 file1 之前将字段 seapeator 设置为 |

awk -F'|' 'NR==FNR{a[$0];next} $1 in a' File2.txt File1.txt

上面的命令对我不起作用(我在 Mac 上,不知道是否重要),但是

awk 'NR==FNR{_[$0];next} ($1 in _)' File2.txt. FS="|" File1.txt

效果不错

【讨论】:

  • @belovedname,欢迎您,请注意:如果您的 file2 中从未包含 |,那么您可以在 BEGIN 程序本身的 BEGIN 部分提及 FS="|" 否则您可以保持答案,因为它现在显示在我的答案中。
  • file2 中是否包含| 无关紧要,因为您从不使用 file2 中的单个字段,只需 $0。
  • @belovedname 您在 Ravinders 答案中编辑的命令在功能上完全相同与其中已有的命令相同,只是您的第一个文件名以 . 结尾,这几乎是当然只是一个错字。在 Mac 上没有任何区别。这些命令中的一个根本不可能为您工作,而另一个则不起作用。
【解决方案2】:

您还可以使用grep 匹配来自 File2.txt 的正则表达式列表以进行精确匹配。

您可以使用sed 来准备比赛。这是一个例子:

sed -E 's/[ \t]*$//; s/^(.*)$/^\1|/' File2.txt
^Carol Haigh|
^Helen Stanley|
^Angela Darvill|
...

然后使用带有sed 的进程作为-fgrep 参数:

grep -f <(sed -E 's/[ \t]*$//; s/^(.*)$/^\1|/' File2.txt) File1.txt
Helen Stanley| text text text text  

由于您的示例 File2.txt 有尾随空格,seds/[ \t]*$//; 作为第一个替换。如果您的实际文件没有这些交易空间,您可以这样做:

grep -f <(sed -E 's/.*/^&|/' File2.txt) File1.txt

Ed Morton 提出了一个很好的观点,即 grep 仍将解释 File2.txt 中的 RE 元字符。您可以使用标志-F,因此只使用文字字符串:

grep -F -f <(sed -E 's/.*/&|/' File2.txt) File1.txt

【讨论】:

  • 您还需要sed 添加转义以使正则表达式元字符文字化,这样P.T.Barnum 这样的名称就不会错误地匹配PAT Barnum。请参阅is-it-possible-to-escape-regex-metacharacters-reliably-with-sed 了解如何做到这一点(但显然使用 awk 的字符串匹配要简单得多、效率更高等)
猜你喜欢
  • 2013-02-12
  • 1970-01-01
  • 2022-09-22
  • 2017-01-02
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2017-11-29
  • 1970-01-01
相关资源
最近更新 更多