【问题标题】:AWK - compare column $1 , append rows together that match (including duplicates)AWK - 比较列 $1 ,将匹配的行附加在一起(包括重复项)
【发布时间】:2022-01-11 08:09:21
【问题描述】:

我正在尝试解析两个包含数千行的 csv 文件。数据将仅根据第一列中的数据进行匹配和附加。我目前正在解析文件并输出到 3 个文件:

1 - key matched
2 - file1 only
3 - file2 only

我遇到的问题是,我注意到一旦匹配成功,它就会移动到下一行,而不是查找其他条目。对于有问题的数据,我宁愿输出包含一些重复项的多行,也不愿错过任何数据。 (例如名称列因输入数据的人而异)

输入文件

file1.csv
topic,group,name,allow
fishing,boaties,dave,yes
fishing,divers,steve,no
flying,red,luke,yes
walking,red,tom,yes

file2.csv
Resource,name,email,funny
fishing,frank,frank@home.com,no
swiming,lee,lee@wallbanger.com,no
driving,lee,lee@wallbanger.com,no

电流输出

key matched
topic,group,name,allow,Resource,name,email,funny
fishing,divers,steve,no,fishing,frank,frank@home.com,no

file1_only
topic,group,user,allow
fishing,divers,steve,no
flying,red,luke,yes
walking,red,tom,yes

file2_only
Resource,user,email,funny
swiming,lee,lee@wallbanger.com,no
driving,lee,lee@wallbanger.com,no

预期输出

key matched
topic,group,name,allow,Resource,name,email,funny
fishing,divers,steve,no,fishing,frank,frank@home.com,no
fishing,boaties,dave,yes,fishing,frank,frank@home.com,no

file1_only
topic,group,user,allow
flying,red,luke,yes
walking,red,tom,yes

file2_only
Resource,user,email,funny
swiming,lee,lee@wallbanger.com,no
driving,lee,lee@wallbanger.com,no

因此,对于文件 1 列 1 中的每个键,它需要输出/附加与文件 2 列 1 中匹配的每个键。

这是我当前的 awk 过滤器。我猜如果可能的话我需要添加一个循环?

BEGIN { FS=OFS="," }
FNR==1 { next }
{ key = $1 }
NR==FNR {
    file1[key] = $0
    next
}
key in file1 {
    print file1[key], $0 > "./out_combined.csv"
    delete file1[key]
    next
}
{
    print > "./out_file2_only.csv"
}
END {
    for (key in file1) {
        print file1[key] > "./out_file1_only.csv"
    }
}

【问题讨论】:

  • file2 column1 中的键是否唯一?
  • 不,目前没有什么是独一无二的,因为这些 csv 文件是通过解析大量日志文件构建的。一些审计练习。
  • 如果 file2.csv 还包含额外的一行 fishing,x,y@z,no ,需要什么输出?
  • 输入多少行?数千?百万?万亿?进行处理的机器上有多少 RAM?你关心输出行的顺序吗?
  • 顺便说一句,file1.csv[key] 应该是语法错误

标签: awk


【解决方案1】:
$ cat tst.awk
BEGIN { FS=OFS="," }
FNR==1 {
    if ( NR==FNR ) {
        file1hdr = $0
    }
    else {
        print file1hdr     > "./out_file1_only.csv"
        print              > "./out_file2_only.csv"
        print file1hdr, $0 > "./out_combined.csv"
    }
    next
}
{ key = $1 }
NR==FNR {
    file1[key,++cnt[key]] = $0
    next
}
{
    file2[key]
    if ( key in cnt ) {
        for ( i=1; i<=cnt[key]; i++ ) {
            print file1[key,i], $0 > "./out_combined.csv"
        }
    }
    else {
        print > "./out_file2_only.csv"
    }
}
END {
    for ( key in cnt ) {
        if ( !(key in file2) ) {
            for ( i=1; i<=cnt[key]; i++ ) {
                print file1[key,i] > "./out_file1_only.csv"
            }
        }
    }
}

$ awk -f tst.awk file1.csv file2.csv

$ head out_*
==> out_combined.csv <==
topic,group,name,allow,Resource,name,email,funny
fishing,boaties,dave,yes,fishing,frank,frank@home.com,no
fishing,divers,steve,no,fishing,frank,frank@home.com,no

==> out_file1_only.csv <==
topic,group,name,allow
flying,red,luke,yes
walking,red,tom,yes

==> out_file2_only.csv <==
Resource,name,email,funny
swiming,lee,lee@wallbanger.com,no
driving,lee,lee@wallbanger.com,no

【讨论】:

  • 感谢 Ed,完美运行。
猜你喜欢
  • 2014-05-27
  • 2019-03-28
  • 1970-01-01
  • 2017-06-19
  • 2011-11-14
  • 2015-04-16
  • 1970-01-01
  • 2017-05-21
  • 2018-10-25
相关资源
最近更新 更多