在 AWK 中打印没有重复的数组

Bum*_*ger 3 awk text-processing join

我希望比较两个文件,只打印具有匹配 ID 号且没有重复记录的记录。

我有两个文件:

file1.txt 包含:

Simons 0987768798980
West 09809867678
Vickers 768774564650
Simons 76867790987
Peterson 24346576865
Simons 76867790987
Holister 87879655456
Peterson 87686765766
Run Code Online (Sandbox Code Playgroud)

并且,file2.txt包含:

768774564650 Harry
76867790987 Steve
0987768798980 Mary
0987768798980 Mary
76856009097 Ali
87879655456 Rick
87686765766 Martin
Run Code Online (Sandbox Code Playgroud)

想要的结果是:

Harry Vickers 768774564650
Steve Simons 76867790987
Mary Simons 0987768798980   
Rick Holister 87879655456
Martin Peterson 87686765766
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的:

ARGV[1]==FILENAME{id2lastname[$2]=$1;id2id[$2]=$2}
ARGV[2]==FILENAME{id2firstname[$1]=$2}

$1 in id2id{print id2firstname[$1],id2lastname[$1],id2id[$1],id2firstname[$1]="",id2id[$1]="",id2lastname[$1]=""}
Run Code Online (Sandbox Code Playgroud)

产生以下输出:

Harry Vickers 768774564650   
Steve Simons 76867790987   
Mary Simons 0987768798980   
Mary     
Rick Holister 87879655456   
Martin Peterson 87686765766 
Run Code Online (Sandbox Code Playgroud)

我很高兴知道为什么这删除了重复记录的姓氏和 ID 号,但保留了名字。

如果该技术很奇怪或非常规,我们深表歉意。我已经很久没有学习了。

如果我的尝试无法修复或您觉得有更好的方法,我很高兴您以不同的方式产生所需的结果,但请:

  • 使用 GAWK(因为我想继续使用它),
  • 尽量保持简单,
  • 并且,解释它是如何工作的,这样我就可以学到一些东西。

αғs*_*нιη 7

使用join如您想保持尽可能简单;

join -1 2 -2 1 -o 2.2 1.1 2.1 <(sort -unk2,2 file1) <(sort -unk1,1 file2) 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

join在第一个文件的第二个字段上,-1 2以第二个文件的第一个字段-2 1作为键。

-o输出这些字段:
第二个文件中的第二个2.2
字段第一个文件中的1.1
第一个字段和第二个文件中的第一个字段2.1

这将第二个字段上的第一个文件作为数字键sort -unk2,2 file1
排序,这将第一个字段上的第二个文件作为数字键排序,sort -unk1,1 file2-u从两个文件中删除重复项。


awk解决方法:

awk '!second_file{ Ids[$2]=$1; next }
     ($1 in Ids) { print $2, Ids[$1], $1 }' file1 second_file=1 <(sort -u file2)
Run Code Online (Sandbox Code Playgroud)


use*_*001 7

打印部分行的原因是在您的代码中,您没有删除要从数组中删除的值,而是用空字符串替换它们的值。

这会导致检查$1 in id2id{ ... }被评估true为空字符串的值。

解决的办法是更换代码id2id[$1]=""delete id2id[$1],然后按预期它应该工作。

这是代码的稍微简化版本:

awk 'NR == FNR { a[$2] = $1; next }
     $1 in a { print a[$1], $2, $1; delete a[$1] }' file1.txt file2.txt
Run Code Online (Sandbox Code Playgroud)

在单线中:

awk 'NR==FNR{a[$2]=$1;next} $1 in a{print a[$1],$2,$1; delete a[$1]}' file1.txt file2.txt
Run Code Online (Sandbox Code Playgroud)

使用 awk 而不是 join 的优点是简单且易于定制。

缺点是在合并前将第一个文件存储在RAM中,因此无法有效处理大文件。