重置awk中的行号计数

moh*_*mad 4 bash awk

我有这样的文件

file.txt的

0   1   a
1   1   b
2   1   d
3   1   d
4   2   g
5   2   a
6   3   b
7   3   d
8   4   d
9   5   g
10   5   g
.
.
.
Run Code Online (Sandbox Code Playgroud)

我希望$1每当第二列中的字段值$2发生变化时,使用awk或bash脚本将第一列中的行号计数重置为0 .

结果

0   1   a
1   1   b
2   1   d
3   1   d
0   2   g
1   2   a
0   3   b
1   3   d
0   4   d
0   5   g
1   5   g
.
.
. 
Run Code Online (Sandbox Code Playgroud)

Kev*_*vin 8

只要你不介意一点多余的内存使用,并且第二列是排序的,我认为这是最有趣的:

awk '{$1=a[$2]+++0;print}' input.txt
Run Code Online (Sandbox Code Playgroud)

  • @doubleDown第一次访问任何索引时,您将获得空字符串("""),因此将分配给`$ 1`而不是`0`; `+ 0`使它打印`0`.如果你想要它1索引,你可以只使用`++ a [$ 2]`,而不是`+ 0`. (2认同)

gho*_*oti 6

这个awk单行程似乎对我有用:

[ghoti@pc ~]$ awk 'prev!=$2{first=0;prev=$2} {$1=first;first++} 1' input.txt
0 1 a
1 1 b
2 1 d
3 1 d
0 2 g
1 2 a
0 3 b
1 3 d
0 4 d
0 5 g
1 5 g
Run Code Online (Sandbox Code Playgroud)

让我们分解脚本,看看它的作用.

  • prev!=$2 {first=0;prev=$2} - 这就是你的柜台重置的原因.由于初始状态prev为空,我们重置第一行输入,这很好.
  • {$1=first;first++} - 对于每一行,设置第一个字段,然后增加我们用来设置第一个字段的变量.
  • 1 - 这是"打印线"的简写.它实际上是一个总是求值为"true"的条件,当条件/语句对缺少一个语句时,该语句默认为"print".

很基本,真的.

当然,一个问题是当你更改awk中任何字段的值时,它会使用设置的任何字段分隔符重写该行,默认情况下它只是一个空格.如果要调整此值,可以设置OFS变量:

[ghoti@pc ~]$ awk -vOFS="   " 'p!=$2{f=0;p=$2}{$1=f;f++}1' input.txt | head -2
0   1   a
1   1   b
Run Code Online (Sandbox Code Playgroud)

盐味.