如果文本中的数字不连续,如何添加一些符号(或仅添加换行符)

如果文本中的数字不连续,如何添加一些符号(或仅添加换行符)

前任:

输入文件

A<0>
A<1>
A_D2<2>
A_D2<3>
A<4>
A_D2<6>
A<9>
A_D2<10>
A<13>

期望的输出:

A<0>
A<1>
A_D2<2>
A_D2<3>
A<4>
-----
A_D2<6>
-----
-----
A<9>
A_D2<10>
-----
-----
A<13>

只需关心尖括号中的数字即可。

如果数字不连续,则添加一些符号(或仅添加换行符),直到数字再次连续。

在本例中,数字 5、7、8、11 和 12 缺失。

任何人都可以使用 awk 或 sed (甚至 grep)命令解决这个问题吗?

我是 Linux 初学者。请解释整个命令行的详细信息。

答案1

不建议使用grep或来执行此操作,因为无法计数并且是sedgrepsed真的很难进行任何类型的算术运算(它必须是基于正则表达式的计数,这对大多数人来说都是不可能的,除了投入的)。

$ awk -F '[<>]' '{ while ($2 >= ++nr) print "---"; print }' file
A<0>
A<1>
A_D2<2>
A_D2<3>
A<4>
---
A_D2<6>
---
---
A<9>
A_D2<10>
---
---
A<13>

代码awk假设0应该是第一个数字,然后维护通缉变量中当前行的行号nr。如果从输入中读取一个数字,需要插入一行或多行,则这是通过循环完成的while(它也会递增nr变量)。

输入的数字<...>是通过指定来解析出来的,<并且>应该用作字段分隔符。该数字位于$2(第二个字段)中。

答案2

这可能远非有效......

$ tr '<' '\t' < testfile | tr '>' ' ' \
  | awk '{ while (NR + shift <= $2) { print "-----"; shift++ }; print }' \
  | tr '\t' '<' \
  | tr ' ' '>'
A<0>
A<1>
A_D2<2>
A_D2<3>
A<4>
-----
A_D2<6>
-----
-----
A<9>
A_D2<10>
-----
-----
A<13>

首先,我用来tr从文件中获取两个制表符分隔的字段。

其次,我tr再次使用空格替换 '>',因为否则我的 awk 命令将失败:-/

这里的 awk 专业人士现在可能会笑:-)

第三,awk-命令将处理的行数与第二个字段进行比较。如果行数较小,它将打印标记并增加该标记,shift并将其添加到先前比较的行数中。

第四和第五:我正在撤消之前使用tr.

我从中得到了一些灵​​感https://unix.stackexchange.com/a/190707/364705

答案3

我不是awk男人,但这似乎也能做到这一点。我始终乐于接受改进:

awk -F '[<>]' -v num=0 '
{
  while(num < $2) {
    print "----";
    num++
  }
  print $1"<"$2">"
  num++
}' file

首先,我们设置字段分隔符以匹配字符<>,因此每行都在这些字符处分割。例如,第一行将分配给$1=A$2=0

然后我们设置变量num=0。我们将其用作行计数器:如果当前行数$2大于行计数器,则 print ----,增加计数器重复,直到两个值相等。然后打印$1<$2>并递增计数器。

答案4

我们可以通过正则表达式使用lookahead和lookbehind来解决这个问题,并且只添加破折号:

$ perl -0777 -pe 's/^.*<(\d+)>.*\n\K(?=.*<(\d+)>.*$)/qq[-----\n] x ($2-$1-1)/gem' file

结果:

A<0>
A<1>
A_D2<2>
A_D2<3>
A<4>
-----
A_D2<6>
-----
-----
A<9>
A_D2<10>
-----
-----
A<13>

相关内容