示例输入文件包含以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中测试)