用于顺序替换模式的 awk 查询

用于顺序替换模式的 awk 查询

我发现下面的 awk 命令可以顺序替换文件中的特定行,但我想知道这是如何工作的。

输入:-

DS: 1
DS: 1
DS: 1
DS: 1
DS: 1
DS: 1
DS: 1

输出:-

DS: 1
DS: 2
DS: 3
DS: 1
DS: 2
DS: 3
DS: 1
DS: 2
DS: 3

awk 命令:-

awk '$1 ~ /DS:/ {$NF=((c++ % count) + 1)} 1' count=3

答案1

我有理由相信工作awk命令是

awk -v count=3 '/DS:/ {$NF=((c++ % count) + 1)} 1' input

input输入文件在哪里。另外,我认为输入文件中应该有 9 行而不是 7 行来生成问题中指定的输出。

下面是它的工作原理。

首先,该选项-v count=3分配3awk多变的 count。如果它按照问题中的方式编写(count=3在命令末尾),3将被分配给外壳变量并且 无法被访问,awk并且会导致被零除错误,因为count将被隐式初始化为0

/DS:/ {$NF=((c++ % count) + 1)}

/DS:/部分是大括号中的块的条件。它代表正则表达式DS:,只能匹配字符串DS:。此条件匹配所有包含 的行DS:

对于所有这些行,变量c都会递增,然后取模count。由于我们没有对该c变量进行显式定义,因此它会隐式初始化0为该代码块首次执行时的值。

然后将结果添加到1并分配给$NF。这里,NF是由字段分隔符分隔的行中的字段数。默认字段分隔符 ( FS) 是空格。请注意,空格FS是一种特殊情况awk,多个连续空格将被视为仅一个字段分隔符。

由于NF是字段数,$NF因此指最后一个字段。在这种情况下,对 的赋值$NF导致 被1替换为通过评估 获得的值((c++ % count) + 1)

Final1代表 true 条件,其后面的代码块被省略。print当条件为真时,其效果是隐含的。由于1始终为 true,因此始终会执行该操作并打印当前行,可能是在最后一个块转换之后。

为了更好地理解该过程,我们可以跟踪awk.awk有一个隐式循环,可以循环输入的行。

  • 第一行:c隐式赋值0c++仍然是0,但它更改c1, (c++ % count)is0模,3所以 is 0, ((c++ % count)+1)is 1,赋值将最后一个字段(在本例中也恰好是最后一个字符)更改为1,最终1打印此行,所以我们得到DS: 1

  • 第二行:c现在1((c++ % count)+1)2并更改c2.最后一个字段更改为2并打印,因此我们得到DS: 2

  • 第三行:类似地,((c++ % count)+1)更改c3并计算为3。我们得到DS: 3.

  • 第四行:现在是%真正生效的时候。(c++ %count)3取模,3等于0,并再次((c++%count)+1) 计算为1。我们得到DS: 1.

等等。这就是它的工作原理。请注意,如果有任何行没有,DS:它们将被逐字打印。

相关内容