使用 awk 计算特定列在文件中出现的次数
Posted
技术标签:
【中文标题】使用 awk 计算特定列在文件中出现的次数【英文标题】:count the number of occurrences in a files for particular column using awk 【发布时间】:2019-01-23 20:46:03 【问题描述】:我有一个文件有以下输入
1,1_2_34_45.csv,2345
2,1_2_34_45.csv,2345
3,1_2_34_45.csv,2345
4,1_2_34_46.csv,2346
5,1_2_34_47.csv,2345
为此我需要以下输出
1_2_34_45.csv,2345,3
1_2_34_46.csv,2346,1
1_2_34_47.csv,2345,1
我试过下面的代码
awk -F , 'a[$2]++ ENDfor(i in a)print i,a[i]' table.txt > count.txt
但它只打印计数,$2 值,但其他列详细信息未显示为所需的输出,请帮助我
【问题讨论】:
不。可能是我在通过手机打字时输入的 如果给定的 $2 有多个 $3 值,输出会是什么样子? 没有 $3 与 CSV 值的总数相同。 【参考方案1】:在数组键中存储您想要的值可能就足够了。
$ awk -F, 'a[$2 FS $3]++ END for(i in a)print i,a[i]' OFS=, input.txt
1_2_34_47.csv,2345,1
1_2_34_46.csv,2346,1
1_2_34_45.csv,2345,3
请注意,使用如此简单的 awk 脚本,无法保证输出顺序。 (即不保证数组顺序。)如果要控制顺序,最好使用额外的数组:
$ awk -F, 'k=$2 FS $3 !a[k]++o[i++]=k END for(j=0;j<i;j++)print o[j],a[o[j]]' OFS=, input.txt
1_2_34_45.csv,2345,3
1_2_34_46.csv,2346,1
1_2_34_47.csv,2345,1
第二个数组有一个递增键,我们可以使用 for 循环作为计数器逐步遍历它。计数器保留输入流中“新”键的原始顺序。
【讨论】:
你能解释一下 !a[k] 场景吗 FWIW 我会通过在 $2 更改时打印而不是等到 END 来保留订单。看起来输入按 $2 排序,如果不是,在调用 awk 之前很容易做到。 @narman12,!a[k]++
是一个条件。值为 0 的变量或数组成员的计算结果为 false。 ++
增加值,但不是在它被访问以用于条件之前,!
否定逻辑。因此,如果该数组成员未设置或0
,则此条件 (1) 为真,并且 (2) 在对其进行评估后递增该值。
@EdMorton,我不反对,按照您的建议进行操作会消除数组的内存占用。但是您仍然需要 END 中的代码(可能是对函数的调用)来处理最后一个键的计数。它开始发展成为不止一个单线。 :-) 如果 OP 提到内存问题或非常大的输入文件,或者在永不结束的流上运行它(如 tail -f
),我将添加类似的内容。
对,我总是写一个 prt() 函数,以便在转换时和从 END 调用。以上是关于使用 awk 计算特定列在文件中出现的次数的主要内容,如果未能解决你的问题,请参考以下文章