UNIX:比较2个文件并附加重复项 - 几乎可以正常工作

时间:2012-12-14 00:35:42

标签: unix awk comparison grep duplicates

我正在开发一个Unix脚本,我必须比较两个文件。一个文件是ID列表(ids.txt,另一个是重复ID列表(duplicate.txt)。我需要比较两个文件,并为ids.txt中找到的每个副本添加一个计数系统。我已经创建了重复文件和ID文件,我只需要比较它们并在重复项的末尾添加数字。到目前为止我已尝试过这个:

awk 'FILENAME=="duplicates.txt" {arr[$0]++}
 FILENAME=="ids.txt" {print $0, arr[$0]} ' duplicates.txt ids.txt

这几乎可以工作,唯一的问题是所有重复项最后都附加了1,但是我需要它来计算每个副本。例如,如果我在文件中有3次dabbot,我需要它说dabbott1 dabbott2 dabbott3。 提前谢谢。

1 个答案:

答案 0 :(得分:1)

以脚本为基础:

awk 'FILENAME=="duplicates.txt" {arr[$0]++}
     FILENAME=="ids.txt"        { if (arr[$0]) printf "%s%d\n", $0, ++cnt[$0];
                                  else print
                                }' \
     duplicates.txt ids.txt

您计算/记录重复项,因此您知道哪些行是重复的。重复文件是否一次或多次列出重复的名称并不重要;两者都可以。

第二个循环注意当前行是否在重复列表中;如果是这样,它打印行后跟一个预先递增的计数器(因此给定副本的第一次出现打印时带有1作为后缀);否则,该行打印不变。

您可以讨论FILENAME = "filename" vs FNR == NR的优点,以区分这两个文件;最终结果是一样的,所以你也可以尝试:

awk 'FNR == NR { arr[$0]++; next }
               { if (arr[$0]) printf "%s%d\n", $0, ++cnt[$0];
                 else print }' duplicates.txt ids.txt

请注意,如果您希望printdabbot1之间没有空格dabbot,则使用1即可。如果空格无关紧要并且您总是需要后缀(如果没有重复,则为0),您只需用printf $0, ++cnt[$0]来代替if而不是printf

如果使用FNR == NR技巧,则甚至不需要预先准备重复文件;你可以简单地使用:

awk 'FNR == NR { arr[$0]++; next }
               { if (arr[$0] > 1) printf "%s%d\n", $0, ++cnt[$0];
                 else print }' ids.txt ids.txt

第一次通过文件,它通过计算它们来排序哪些记录是重复的。第二次通过该文件,它知道哪些是重复的(arr中的计数超过1)并且可以在这些行上打印后缀。