我在互联网上找到了以下 AWK 程序,并对其进行了稍微调整以查看第 $2 列:
{ a[$2,NR]=$0; c[$2]++ }
END {
for( k in a ) {
split(k,b,SUBSEP)
t=c[b[1]] # added this bit to capture count
if( b[1] in c && t>1 ) { # added && t>1 only print if count more than 1
print RS "TIMES ID" RS c[b[1]] " " b[1] RS
delete c[b[1]]
}
for(i=1;i<=NR;i++) if( a[b[1],i] ) {
if(t>1){print a[b[1],i]} # added if(t>1) only print lines if count more than 1
delete a[b[1],i]
}
}
}
给定以下文件:
abc,2,3
def,3,4
ghi,2,3
jkl,5,9
mno,3,2
命令运行后输出如下:
命令:awk -F, -f find_duplicates.awk 重复项
Output:
TIMES ID
2 2
abc,2,3
ghi,2,3
TIMES ID
2 3
def,3,4
mno,3,2
这很好。
我想了解 AWK 程序中发生了什么。
我明白第一行正在将每一行加载到多维数组中?
因此文件的第一行将是 a['2','1']='abc,2,3'
等等。
但是我对 c[$2]++ 的作用以及 split(k,b,SUBSEP) 的意义是什么有点了解
??
如果有人可以逐行解释此 AWK 程序中发生的情况,我将不胜感激。
谢谢。
最佳答案
增量运算符只是将引用变量的值加一。因此,c[$2]++
获取 c[$2]
的值并加一。如果 $2
之前是 a
并且 c["a"]
之前是 3,那么之后它的值将是 4
。因此,c
会跟踪您看到的每个 $2
值的数量。
for (k in a)
循环遍历 a
的键。如果第一行 $2
的值为 "a"
,则 k
的第一个值为 "a","1"(其中 1 是行号)。下一次,它将是第二行的 $2
值和行号 2 的组合,依此类推。
split(k,b,SUBSEP)
将从 k
中的复合值创建一个新数组 b
,即基本上重建复合键中进入 a
的部分。 b[1]
中的值现在将是创建 a
中相应值时 $2
中的值,并且 a
中的值b[2]
将是相应的行号。
最后的循环效率有些低;它循环遍历所有可能的行号,如果该 ID 和行号的条目不存在,则立即跳到下一个。因为它在外部循环 for (k in a)
内运行,所以如果您有大量输入,它将重复很多次(它将循环遍历每个输入行的所有输入行号) )。以增加一些额外内存为代价,增量构建最终输出,然后在循环遍历所有 a
后将其全部打印出来,此时您已经处理了所有输入,这会更有效无论如何,线路。也许是这样的:
END {
for (k in a) {
split (k,b,SUBSEP)
if (c[b[1]] > 1) {
if (! o[b[1]]) o[b[1]] = c[b[1]] " " b[1] RS
o[b[1]] = o[b[1]] RS a[k]
}
delete a[k]
}
for (q in o) print o[q] RS
}
更新:删除了过早删除的c[b[1]]
。
关于linux - AWK 报告重复行和计数,程序说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12357910/