【问题标题】:Comparing two csv files and updating a field according to the comparison using awk比较两个 csv 文件并根据使用 awk 的比较更新一个字段
【发布时间】:2017-02-19 02:08:43
【问题描述】:

我有以下文件:

file1.csv

ID, Name, Address, Phone, Favorite Color/Colors Match
1, Jim, 12 Main,123-456-7890, Blue
2, Kim,11 Bush,987-654-3210, RedGreen
3, Tim,33 Main,111-111-1111,YellowOrange
4, Zim,66 Main,111-555-1111,YellowOrange

file2.csv

ID, Name, Address, Phone, Favorite Color/Colors Match, Blood Type, Left/Right Handed
1, Jon, 122 Main,333-456-7890, Red, A Pos, Right
2, Tom,111 Bush,999-654-3210, RedGreen, A Neg, Right
3, Tam,333 Main,111-222-1111,YellowOrange, O Neg, Left
4, Zam,99 Main,555-555-1111,Blue, A Pos, Left

我想要每个文件的以下输出:

file1.csv

ID, Name, Address, Phone, Favorite Color/Colors Match
1, Jim, 12 Main,123-456-7890, No Match
2, Kim,11 Bush,987-654-3210, Match
3, Tim,33 Main,111-111-1111,Match
 4, Zim,66 Main,111-555-1111,No Match

file2.csv

ID, Name, Address, Phone, Favorite Color/Colors Match, Blood Type, Left/Right Handed
1, Jon, 122 Main,333-456-7890, No Match, A Pos, Right
2, Tom,111 Bush,999-654-3210, Match, A Neg, Right
3, Tam,333 Main,111-222-1111,Match, O Neg, Left
4, Zam,99 Main,555-555-1111,No Match, A Pos, Left

基本上,我想根据两个单独文件中的 ID 字段比较一个字段,并确定它们是否匹配。

我尝试使用 awk 进行此操作:

awk -F',' 'NR==FNR {n[$5]=$0} {if ($1 == n[$1] && $5 == n[$5])    
n[$5]="Match"; else $n[5]="No Match";}1' OFS=, file1.csv file2.csv > testfile.csv

但我得到了一些意想不到的结果。我是 awk 的新手,所以任何建议都将不胜感激。谢谢。

【问题讨论】:

    标签: linux bash csv awk


    【解决方案1】:

    你可以像这样使用 awk:

    cat csv.awk
    
    BEGIN{FS=OFS=","}                
    FNR==NR {
       a[$1 SUBSEP $5]
       next
    }
    {
       $5 = (($1 SUBSEP $5) in a)?"Match":"No Match"
    }
    1
    

    然后将其用作:

    awk -f csv.awk file2.csv file1.csv
    
    ID, Name, Address, Phone,Match
    1, Jim, 12 Main,123-456-7890,No Match
    2, Kim,11 Bush,987-654-3210,Match
    3, Tim,33 Main,111-111-1111,Match
    4, Zim,66 Main,111-555-1111,No Match
    

    还有:

    awk -f csv.awk file1.csv file2.csv
    
    ID, Name, Address, Phone,Match, Blood Type, Left/Right Handed
    1, Jon, 122 Main,333-456-7890,No Match, A Pos, Right
    2, Tom,111 Bush,999-654-3210,Match, A Neg, Right
    3, Tam,333 Main,111-222-1111,Match, O Neg, Left
    4, Zam,99 Main,555-555-1111,No Match, A Pos, Left
    

    更新:如果您想使用单个 awk 命令,就在这里。

    cat csv.awk 
    
    BEGIN{FS=OFS=","}
    {
       key = $1 SUBSEP $5 
    }
    FNR == NR { 
       a[key]
       next
    }
    FILENAME == ARGV[2] { 
       if (key in a) {
          $5 = "Match"
          b[key]
       }
       else
          $5 = "No Match"
       print > "_" ARGV[2]
       next
    }
    {
       $5 = (key in b)?"Match":"No Match"
       print > "_" ARGV[3]
    }
    

    然后执行为:

    awk -f csv.awk file2.csv file1.csv file2.csv &&
    mv _file1.csv file1.csv &&
    mv _filw2.csv file2.csv
    

    【讨论】:

    • 只是出于好奇,您的第一个示例中的 awk -f csv.awk file2.csv file1.csv 是做什么的?
    • awk -f csv.awk file2.csv file1.csv 正在为file1.csv 生成您想要的输出,而awk -f csv.awk file1.csv file2.csv 正在为file2.csv 生成输出
    • 不是真的,但我认为这可能与我的原始文件有关(这是此处的示例数据)。由于某种原因,awk 似乎无法正确计算字段,并且只附加结果而不是替换。
    • 对。我很抱歉。我不能在这里分享数据。不过还是谢谢你。我相信一旦我弄清楚我自己的文件存在什么问题,您的解决方案应该可以正常工作。
    • 是的。那是我的档案。有没有切换字段。现在效果很好。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-09-05
    • 2014-10-12
    • 2023-03-11
    • 2014-12-25
    • 1970-01-01
    • 2016-06-23
    • 2017-01-31
    相关资源
    最近更新 更多