AWK:比较 2 个 csv 文件中的 2 列,输出到第三个。如何获得与另一个文件不匹配的输出?

Posted

技术标签:

【中文标题】AWK:比较 2 个 csv 文件中的 2 列,输出到第三个。如何获得与另一个文件不匹配的输出?【英文标题】:AWK : comparing 2 columns from 2 csv files, outputting to a third. How do I also get the output that doesnt match to another file? 【发布时间】:2022-01-07 13:56:38 【问题描述】:

我目前有以下脚本: awk -F, 'NR==FNR a[$1 FS $4]=$0; next $1 FS $4 in a printf a[$1 FS $4]; sub($1 FS $4,""); print ' file1.csv file2.csv > combined.csv

这会比较两个 csv 文件中的两列 1 和 4,并将两个文件的结果输出到 combine.csv。是否可以从文件 1 和文件 2 中输出与具有相同 awk 行的其他文件不匹配的行?还是我需要单独解析?

File1
ResourceName,ResourceType,PatternType,User,Host,Operation,PermissionType
BIG.TestTopic,Cluster,LITERAL,Bigboy,*,Create,Allow
BIG.PRETopic,Cluster,LITERAL,Smallboy,*,Create,Allow
BIG.DEVtopic,Cluster,LITERAL,Oldboy,*,DescribeConfigs,Allow

File2
topic,groupName,Name,User,email,team,contact,teamemail,date,clienttype
BIG.TestTopic,BIG.ConsumerGroup,Bobby,Bigboy,bobby@example.com,team 1,Bobby,boys@example.com,2021-11-26T10:10:17Z,Consumer
BIG.DEVtopic,BIG.ConsumerGroup,Bobby,Oldboy,bobby@example.com,team 1,Bobby,boys@example.com,2021-11-26T10:10:17Z,Consumer
BIG.TestTopic,BIG.ConsumerGroup,Susan,Younglady,younglady@example.com,team 1,Susan,girls@example.com,2021-11-26T10:10:17Z,Producer

combined
BIG.TestTopic,Cluster,LITERAL,Bigboy,*,Create,Allow,BIG.TestTopic,BIG.ConsumerGroup,Bobby,Bigboy,bobby@example.com,team 1,Bobby,boys@example.com,2021-11-26T10:10:17Z,Consumer
BIG.DEVtopic,Cluster,LITERAL,Oldboy,*,DescribeConfigs,Allow,BIG.DEVtopic,BIG.ConsumerGroup,Bobby,Oldboy,bobby@example.com,team 1,Bobby,boys@example.com,2021-11-26T10:10:17Z,Consumer

Wanted additional files:

non matched file1:
BIG.PRETopic,Cluster,LITERAL,Smallboy,*,Create,Allow

non matched file2:
BIG.TestTopic,BIG.ConsumerGroup,Susan,Younglady,younglady@example.com,team 1,Susan,girls@example.com,2021-11-26T10:10:17Z,Producer```

again, I might be trying to do too much in one line? would it be wiser to run another parse?

【问题讨论】:

您可以将awk/print(f) 命令的输出重定向到特定文件,因此,我可能在awk 代码中只有3 个逻辑路径,这些逻辑路径导致print(f) 命令转到3 个不同的输出文件 每个文件中的 $1 和 $4 组合在该文件中是否唯一? 【参考方案1】:

假设 $1 和 $4 的密钥对在每个输入文件中是唯一的,然后在每个 Unix 机器上的任何 shell 中使用任何 awk:

$ cat tst.awk
BEGIN  FS=OFS="," 
FNR==1  next 
 key = $1 FS $4 
NR==FNR 
    file1[key] = $0
    next

key in file1 
    print file1[key], $0 > "out_combined"
    delete file1[key]
    next


    print > "out_file2_only"

END 
    for (key in file1) 
        print file1[key] > "out_file1_only"
    

$ awk -f tst.awk file1,2

$ head out_*
==> out_combined <==
BIG.TestTopic,Cluster,LITERAL,Bigboy,*,Create,Allow,BIG.TestTopic,BIG.ConsumerGroup,Bobby,Bigboy,bobby@example.com,team 1,Bobby,boys@example.com,2021-11-26T10:10:17Z,Consumer
BIG.DEVtopic,Cluster,LITERAL,Oldboy,*,DescribeConfigs,Allow,BIG.DEVtopic,BIG.ConsumerGroup,Bobby,Oldboy,bobby@example.com,team 1,Bobby,boys@example.com,2021-11-26T10:10:17Z,Consumer

==> out_file1_only <==
BIG.PRETopic,Cluster,LITERAL,Smallboy,*,Create,Allow

==> out_file2_only <==
BIG.TestTopic,BIG.ConsumerGroup,Susan,Younglady,younglady@example.com,team 1,Susan,girls@example.com,2021-11-26T10:10:17Z,Producer

out_file1_only 中的行顺序将由 in 运算符打乱 - 如果这是一个问题,请告诉我们,因为保留输入顺序很容易调整。

【讨论】:

哇,谢谢,这似乎工作得很好。回答你之前的问题。虽然列中应该包含唯一信息,但我注意到存在数据在字段之间重复的情况。但我想我可以通过首先解析文件并替换“。”来解决这个问题。在带有“_”或类似名称的一列中。 如果这是一个问题,只需使用包含这些问题的示例数据提出一个新的后续问题。

以上是关于AWK:比较 2 个 csv 文件中的 2 列,输出到第三个。如何获得与另一个文件不匹配的输出?的主要内容,如果未能解决你的问题,请参考以下文章

两个文件中的AWK列匹配,打印不同的列

使用 awk 计算特定列在文件中出现的次数

使用基于动态列作为变量的AWK比较2个文件,并打印差异A-B和B-A

在 BASH 脚本中使用“awk”将列添加到 CSV 文件的末尾

使用 awk 忽略 CSV 文件字段中的逗号

使用 awk 或 perl 从 CSV 中提取特定列(解析)