我有一个文件,其中有一个我想替换的字符,但我还希望每个要替换的字符实例都用字符串替换中的数字进行迭代。
一些文件.txt
[H
A
[H
B
[H
C
我想用“ </pre></div><div id=cat$n><pre>
”替换“[H”,其中 $n 是替换次数的迭代器。因此,第一个替换将是 1、2、3、4、n++ 等等。
有没有办法做到这一点sed
?
答案1
Perl 来救援!
perl -pe 'BEGIN { $n = 1 } s%\[H%</pre></div><div id=cat$n><pre>% && $n++' filename
-p
逐行读取输入并打印代码对其执行的操作BEGIN { ... }
在程序输入之前运行s%pattern%replacement%
替换pattern
为replacement
。\[
需要反斜杠,因为[
在正则表达式中是特殊的&& $n++
如果替换成功,则返回 true,因此运行下一个命令:并增加计数器$n
。
答案2
另一种 awk 方法,将其[H
视为记录分隔符:
awk -v RS='\\[H' 'NR>1{printf "</pre></div><div id=cat%d><pre>",NR-1}1'
[H
除第一条记录外,所有记录前面都有,因此,对于这些记录,我在记录本身前面打印一个</pre></div><div id=catN><pre>
,其中N = NR - 1
(NR
是记录编号)。
$ awk -v RS='\\[H' 'NR>1{printf "</pre></div><div id=cat%d><pre>",NR-1}1' foo.txt
</pre></div><div id=cat1><pre>
A
</pre></div><div id=cat2><pre>
B
</pre></div><div id=cat3><pre>
C
使用 GNU awk,您可以使用新的就地修改模块:
gawk -i inplace -v RS='\\[H' 'NR>1{printf "</pre></div><div id=cat%d><pre>",NR-1}1' foo.txt
这与 类似sed -i
。
答案3
AWK
版本。请注意如何[
转义以及引号如何组织以允许counter
变量在 中扩展"</pre></div><div id=cat"counter"><pre>"
:
$ awk '{ if ( $0~/\[H/ ){\
> counter++; sub(/\[H/,"</pre></div><div id=cat"counter"><pre>")\
> }; print }' test_input.txt
</pre></div><div id=cat1><pre>
A
</pre></div><div id=cat2><pre>
B
</pre></div><div id=cat3><pre>
C
</pre></div><div id=cat4><pre>
除非你正在使用gawk
,否则使用gawk '...' input_file.txt > /tmp/tmp.txt && mv /tmp/tmp.txt input_file.txt
方法用编辑版本替换原始文件
添加
正如 muru 所建议的,代码可以简化为
awk '/\[H/{counter++; sub(/\[H/,"</pre></div><div id=cat"counter"><pre>")}1' test_input.txt