linux - AWK 报告重复行和计数,程序说明

标签 linux bash unix awk

我在互联网上找到了以下 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/

相关文章:

Linux - 查找在最后 X 秒内创建的文件

c++ - Nodejs 和 UNIX 新手 : run node command in a cpp program

linux - 在 awk 命令中使用 pstree

Bash 脚本通过删除最后访问的文件来限制目录大小

linux - 将 grep 输出通过管道传输到 sed 以替换整行

Perl 未初始化警告

linux - 如何使用完整路径或文件名显示 'grep' 结果

mysql - Cron 作业每分钟超过 100 个,太多了吗?

linux - centos mongodb 包未签名

linux - 通过公共(public)互联网连接到树莓派