awk 打印新列,当第一列更改时,该列会更改数字

awk 打印新列,当第一列更改时,该列会更改数字

我一直试图根据其他例子自己做到这一点,但失败了。我希望 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

相关内容