我正在开发一个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。 提前谢谢。
答案 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
请注意,如果您希望print
与dabbot1
之间没有空格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
)并且可以在这些行上打印后缀。