根据多列中的值在单独的列中添加重复次数

根据多列中的值在单独的列中添加重复次数

我试图根据第 1、2 和 3 列添加管道分隔文件最后一列中出现的次数。

我努力了awk '{ print $0 "|" ++count[$1,$2,$3] }'

但它只在所有行的最后一列中生成数字 1,添加了一个额外的管道,如下所示

123|456365|PASS|566563|Apple||1
123|456365|PASS|566563|Apple||1
123|456365|FAIL|34322|Apple1||1
123|456365|FAIL|35322|Apple2||1

如果有人可以帮助我让它工作以获得下面的预期输出,那将非常有帮助。

输入文件

123|456365|PASS|566563|Apple
123|456365|FAIL|34322|Apple1
123|456365|FAIL|35322|Apple2
123|456335|PASS|56655|Apple34
123|456335|FAIL|34325|Apple53
123|34343|PASS|35323|Apple1
123|34343|PASS|34342|Apple13
123|34343|PASS|343442|Apple13

预期产出

123|456365|PASS|566563|Apple|1
123|456365|FAIL|34322|Apple1|1
123|456365|FAIL|35322|Apple2|2
123|456335|PASS|56655|Apple34|1
123|456335|FAIL|34325|Apple53|1
123|34343|PASS|35323|Apple1|1
123|34343|PASS|34342|Apple13|2
123|34343|PASS|343442|Apple13|3

答案1

您需要告诉 awk 什么是字段分隔符:

awk -F'|' -v OFS='|' '{ print $0, ++count[$1,$2,$3] }' infile

我们-F定义了输入字段分隔符并-v OFS定义了输出字段分隔符;相反,我们可以同时使用BEGIN{ FS=OFS="|" }两者,例如:

awk 'BEGIN{ FS=OFS="|" } { print $0, ++count[$1,$2,$3] }' infile

答案2

使用 Raku(以前称为 Perl_6)

raku -ne ' state %seen; print($_, "|"); for $_.split("|").[0..2].join() { (++%seen{$_}).put };'

或者

raku -ne ' state %seen; print($_, "|"); ( ++%seen{$_} ).put for .split("|").[0..2].join;' 

输入示例:

123|456365|PASS|566563|Apple
123|456365|FAIL|34322|Apple1
123|456365|FAIL|35322|Apple2
123|456335|PASS|56655|Apple34
123|456335|FAIL|34325|Apple53
123|34343|PASS|35323|Apple1
123|34343|PASS|34342|Apple13
123|34343|PASS|343442|Apple13

示例输出:

123|456365|PASS|566563|Apple|1
123|456365|FAIL|34322|Apple1|1
123|456365|FAIL|35322|Apple2|2
123|456335|PASS|56655|Apple34|1
123|456335|FAIL|34325|Apple53|1
123|34343|PASS|35323|Apple1|1
123|34343|PASS|34342|Apple13|2
123|34343|PASS|343442|Apple13|3

以上是用 Raku(Perl 编程语言家族的成员)编写的解决方案。简而言之,raku是在命令行上使用-ne(逐行,非自动打印)标志运行。哈希值%seenstate单行开头的 -d。这允许%seen只初始化一次。在第二个语句中,后面跟有 a 的原始行|print-ed(没有换行符)。然后,在第三个语句中,前三列被split打开|并重新join编辑,并且获得的每个值都用于根据其唯一的字符串值++%seen{$_}来增加哈希值。%seen增加的值是put为了完成解决方案。

https://raku.org

相关内容