为同一列中的重复字段添加后缀



示例输入文件包含以TAB分隔字段的行:

raw1    aaa    wer
raw2    bbb    dfg
raw3    ccc    fgh
raw4    ccc    etr
raw5    aaa    cbg
raw6    aaa    dfg

我需要添加后缀(dupl)到第二列,如果它的值出现在任何其他行的第二列

以上输入的期望输出为:

raw1    aaa(dupl)   wer
raw2    bbb dfg
raw3    ccc(dupl)   fgh
raw4    ccc(dupl)   etr
raw5    aaa(dupl)   cbg
raw6    aaa(dupl)   dfg

现在我有以下代码,但它不能有效地工作与巨大的输入文件:

cut -d$'t' -f2 input|
sort|
uniq -c|
awk '$1>1{print $2}'|
while read dup;do gawk -F$'t' -i inplace -va=$dup '$2==a{$2=a"(dupl)"}1' OFS=$'t' input;done

使用单个awk或sed命令,而不使用上面的多个管道,实现相同功能的更简单方法是什么?

我将按照以下方式利用GNUAWK来完成这项任务,让file.txt内容为

raw1    aaa wer
raw2    bbb dfg
raw3    ccc fgh
raw4    ccc etr
raw5    aaa cbg
raw6    aaa dfg

然后

awk 'BEGIN{FS=OFS="t"}FNR==NR{arr[$2]+=1;next}arr[$2]>1{$2=$2 "(dupl)"}{print}' file.txt file.txt

给输出

raw1    aaa(dupl)   wer
raw2    bbb dfg
raw3    ccc(dupl)   fgh
raw4    ccc(dupl)   etr
raw5    aaa(dupl)   cbg
raw6    aaa(dupl)   dfg

解释:我通知GNUAWK制表符(t)既是字段分隔符(FS)和输出字段分隔符(OFS),我运行file.txt两次,第一次传递用于构建数组arr,因此键是其外观的第二个字段和值,然后在第二次传递中有超过1个发生我将(dupl)作为后缀添加到第二个字段,对于每一行我print它。

(在GNU Awk 5.0.1中测试)

最新更新