awk 输出不匹配的行

Posted

技术标签:

【中文标题】awk 输出不匹配的行【英文标题】:Awk output unmatched rows 【发布时间】:2021-12-08 04:15:41 【问题描述】:

我有 awk 命令输出匹配的行数据比较 2 列, 虽然我想输出相反的、不匹配的数据。

#file1.csv
box1,apple
box2,banana


#file2.csv
data24,box1,apple,text
date25,box1,banana,text

我有 AWK,

awk -F',' 'NR==FNRa[$1,$2]; next ($2,$3) in a' file1.csv file2.csv

输出如下:

data24,box1,apple,text

并且想拥有:

banana,box2

在这种情况下,简单的否定似乎不起作用,请问您有什么想法吗? 试过了:

awk -F',' 'NR==FNRa[$1,$2]=1; next !($2,$1) in a' file1.csv file2.csv

将输出:

data24,box1,apple,text
date25,box1,banana,text

【问题讨论】:

(a) 您发布的awk 脚本不会产生指定的输出。 (b) 您正在寻找($2,$3) in a,但例如在file2.csv 中,$3date24date25,它们永远不会是in a。我认为您使用了错误的列。 抱歉,已更新为当前版本 我不太了解awk,但你不能用<>!= 替换== 吗? 在尝试了您的代码(Ubuntu 18.04)后,我根本没有得到任何输出。 请edit您的问题向我们展示您尝试使用但不起作用的“简单否定”。您发布的预期输出需要做的不仅仅是output the opposite, unmatched data,例如它不会打印 file2 中没有出现在 file1 中的值,它会以与当前工作命令不同的顺序打印不同的字段。因此,请确保根据您发布的输入,您发布的预期输出正是您想要的(如果您真的不希望添加这些空白,请删除您在 ,s 之后添加的空白)。跨度> 【参考方案1】:
$ awk 'BEGINFS=OFS="," NR==FNRa[$2,$3]; next !(($1,$2) in a)print $2, $1' file2.csv file1.csv
banana,box2

【讨论】:

谢谢埃德!你的答案是最干净且易于使用的:)【参考方案2】:

您可以反转操作,而不是颠倒逻辑:

awk -F',' 'NR==FNRa[$1,$2]; next ($2,$3) in a next1' file1.csv file2.csv
date25,box1,banana,text

或者:

awk  'BEGINFS=OFS="," 
NR==FNRa[$1,$2]; next ($2,$3) in a next print $2, $3' file1.csv file2.csv
box1,banana

【讨论】:

A code-only answer is not high quality。虽然此代码可能很有用,但您可以通过说明其工作原理、工作方式、何时应该使用以及它的局限性来改进它。请edit您的回答包括解释和相关文档的链接。 那条评论是 BS 有几个原因:1) 使用的代码是 OP 的代码,有一个明显的小改动,可以解决他的问题;2) 小改动是用 注释的,而不是颠倒逻辑上,您可以反转既响应他的问题又响应答案本身的动作 3)您是小气和机械。【参考方案3】:

假设:

两个文件都用逗号分隔 从file1.csv 中查找与file2.csv 中的#2 和#3 字段不匹配的行 对于此类条目(来自file1.csv)以相反的顺序打印字段(OP 显示的最终输出为banana,box2,这是box2,banana 的相反顺序,如file1.csv 中所列)

对 OP 的 awk 代码的一些修改:

awk '
BEGIN    FS=OFS="," 
NR==FNR  a[$1 FS $2] ; next            # add a delimiter to allow for splitting of index later
         delete a[$2 FS $3]            # delete file #1 entries if found in file #2
END      for (i in a)                  # anything left in array was not found in file #2
              split(i,arr,FS)            # split index on delimiter
              print arr[2],arr[1]        # print fields in reverse order
          
        
' file1.csv file2.csv

这会生成:

banana,box2

【讨论】:

以上是关于awk 输出不匹配的行的主要内容,如果未能解决你的问题,请参考以下文章

Linux提取不匹配字符串的行和列(awk函数)

Zabbix自定义参数监控和awk命令

Linux的文本编辑diff & sed & awk & grep

sed与awk

linux-grep awk sed

如何获取从最后一个匹配到文件末尾的行?