计算特定行之前的 TAB/SPACES

计算特定行之前的 TAB/SPACES

我有一个要求,我需要识别文件中的一个字段,如果找到,我将必须添加一个新行并添加一些文本。但我想计算找到的单词之前的空格数,以便我可以在该数量的空格加上 2 个额外空格之后添加一个新行。例如

输入文件:

  <tt:abcdef>

  .

  .

  .
  
  </tt:abcdef>

在上面的输入文件中,我之前有 2 个空格<tt:abcdef>,我想计算这些空格,然后编写一个新行,如下所示

预期输出文件:

  <tt:abcdef>

     <tt:newvar>

  .

  .

  .
  
  </tt:abcdef>

答案1

如果您的输入像您所显示的那样简单和常规,并且您没有也无法安装 xmlstarlet 等,那么您可以在每个 Unix 机器上的任何 shell 中使用任何 awk:

$ awk '{print} sub(/<tt:abcdef>/,"  "){print $0 "<tt:newvar>"}' file
  <tt:abcdef>
    <tt:newvar>

  .

  .

  .

  </tt:abcdef>

上面的代码不计算空格,它只是重用匹配行上存在的任何前导空格。它并不是为了健壮,只是为了将您提供的输入更改为您提供的输出。如果您需要更多,请编辑您的问题以提供更真正具有代表性的示例输入/输出以及对您的要求的更好解释。

答案2

使用(以前称为 Perl_6)

raku -pe 's/^  (\s+) \<tt\:abcdef\> /{$/}\n$0  <tt:newvar>/;'

或者

raku -pe 's[^  (\s+) \<tt\:abcdef\> ]="{$/}\n$0  <tt:newvar>";'  

输入示例:

  <tt:abcdef>
  .
  .
  .
  </tt:abcdef>

示例输出:

  <tt:abcdef>
    <tt:newvar>
  .
  .
  .
  </tt:abcdef>

上面是用 Raku(Perl 编程语言家族的成员)编写的答案。简而言之,-pe自动打印逐行标志用于实现传统的s///替换习惯用法(在第二个示例中写为s[…]="…".

因为您要求^ (\s+) \<tt\:abcdef\>在输出中完全再现识别序列,所以匹配变量$/包含在s///运算符的右半部分(替换)中。空格数(\s+)被捕获$0并添加回替换中。请注意,上面的解决方案显示$/{$/},即在代码块内,但实际上(根据您的要求),花括号是不必要的。

以上是最简单的解决方案。事实上,您可能会在混乱的文本文件中看到不匹配的标签,因此您可能确实需要考虑检测标签对(需要更复杂的解决方案)。

https://raku.org

相关内容