我有一个要求,我需要识别文件中的一个字段,如果找到,我将必须添加一个新行并添加一些文本。但我想计算找到的单词之前的空格数,以便我可以在该数量的空格加上 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
并添加回替换中。请注意,上面的解决方案显示$/
为{$/}
,即在代码块内,但实际上(根据您的要求),花括号是不必要的。
以上是最简单的解决方案。事实上,您可能会在混乱的文本文件中看到不匹配的标签,因此您可能确实需要考虑检测标签对(需要更复杂的解决方案)。