我一直试图根据其他例子自己做到这一点,但失败了。我希望 awk 重新打印一个制表符分隔的文件,但在末尾添加一个额外的列,该列从 1 开始,并且只要 column1 相同就会增加,当 column1 具有新值时,最后一列将重置为 1....
简单示例,如果第 1-3 列为输入且输出有最后一列:
A11R Q9Y5X3 SNX5 1
A12L Q9Y316 MEMO1 1
A12L Q70CQ2 USP34 2
A12L Q8N7H5 PAF1 3
A12L Q8IZL8 PELP1 4
A13L Q5SY16 NOL9 1
A13L Q6P1J9 CDC73 2
A13L Q8WVC0 LEO1 3
A13L Q9Y4W2 LAS1L 4
A13L Q6PD62 CTR9 5
我知道我首先需要读取文件并创建一个第 1 列值的数组,然后根据 if 条件打印文件,其中 if column1 与前一行相同,i++
我试过:
awk '{A[++c] = $1} END {d=1; for ( i = 1; NR == i; i++ ) {if (A[i] = A[i-1]) {d++} else {d=1}; print d, $0}}'
但显然我缺少一些关于其工作原理的基础知识。
答案1
$ awk -F '\t' 'BEGIN { OFS=FS } $1 != save { counter = 1; save = $1 } { print $0, counter++ }' file
A11R Q9Y5X3 SNX5 1
A12L Q9Y316 MEMO1 1
A12L Q70CQ2 USP34 2
A12L Q8N7H5 PAF1 3
A12L Q8IZL8 PELP1 4
A13L Q5SY16 NOL9 1
A13L Q6P1J9 CDC73 2
A13L Q8WVC0 LEO1 3
A13L Q9Y4W2 LAS1L 4
A13L Q6PD62 CTR9 5
该awk
代码将第一个字段的值与 中记住的值进行比较save
。如果值不同,则计数器counter
重置为 1,并且使用第一个字段的值更新记住的值。
然后输出该行,并将计数器添加为最后一个字段(并递增)。
答案2
根据您的示例,您只需要记住上次运行的第一个字段的值和计数器变量:
awk -F'\t' 'BEGIN{ OFS=FS }
{
# if same field, increment counter, else reset counter
count=(last==$1 ? ++count : 1)
# remember first field
last=$1
print $0, count
}' file
答案3
使用米勒:
$ mlr --tsv -N step -a counter -f 1 -g 1 file
-N
文件是无标题的。
step
动词用于计算连续记录之间的某些内容(计数器、ewma 等),可以按记录中的某些字段进行分组。
以下命令给出类似的结果,但计数器被添加为第一个字段。
$ mlr --tsv -N cat -n -g 1 file