0

我正在编写一个 Unix 脚本,我必须在其中比较 2 个文件。一个文件是 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,但我需要它来计算每个重复项。例如,如果我在文件中有 dabbott 3 次,我需要它说 dabbott1 dabbott2 dabbott3。提前致谢。

4

1 回答 1

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

请注意,print如果您希望在和dabbot1之间没有空格,则使用不可行。如果空格无关紧要并且您总是想要一个后缀(如果没有重复则为 0),您可以只写而不是with 。dabbot1printf $0, ++cnt[$0]ifprintf

如果你使用这个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)并且可以在这些行上打印后缀。

于 2012-12-14T04:18:32.440 回答