【发布时间】:2012-12-29 09:02:25
【问题描述】:
我想插入一行
<hr />
在文件中每次出现的标题 2 行之上 - 例如,在此模式之上
<h2>variable pattern here</h2>
所以上面应该变成
<hr />
<h2>variable pattern here</h2>
如何使用 Vim、Sed 或 Perl 做到这一点?
【问题讨论】:
-
你自己有没有尝试过?
我想插入一行
<hr />
在文件中每次出现的标题 2 行之上 - 例如,在此模式之上
<h2>variable pattern here</h2>
所以上面应该变成
<hr />
<h2>variable pattern here</h2>
如何使用 Vim、Sed 或 Perl 做到这一点?
【问题讨论】:
使用sed,您可以使用sed '/<h2>/i <hr />':
$ cat file
<html>
<h2>variable pattern here</h2>
<h3>not here</h3>
<h2>heading</h2>
<h2>Something</h2>
$ sed '/<h2>/i <hr />' file
<html>
<hr />
<h2>variable pattern here</h2>
<h3>not here</h3>
<hr />
<h2>heading</h2>
<hr />
<h2>Something</h2>
第一部分/<h2>/ 匹配包含<h2> 的行,第二部分使用i 命令在匹配行上方插入<hr />。
sed 的一个不错的选项是-i,这会将更改保存回文件而不是打印到stdout,但首先要确保更改正确。
sed -i '/<h2>/i <hr />' file
【讨论】:
/i 的作用?
use strict;
use warnings;
use Tie::File;
tie my @file, 'example.html'
or die "Unable to tie file: $!";
@file = map { m!<h2>.*</h2>!
? ( "<hr />", $_ )
: $_ } @file;
untie @file;
【讨论】:
vim方式:
cmd :g/<h2>/normal O<hr /> 将完成这项工作。
在这里看到它:(我从 sudo_O 中拿了例子)
【讨论】:
在 Vim 中执行此操作的众多方法之一:
:g/h2/norm O<hr /><CR>
细分:
:g[lobal] 作用于与模式匹配的每一行,参见:h :global。
h2 我们正在寻找的模式,它可能会变得更智能一些。
norm[al] 运行正常模式命令,参见:h :normal。
O 在当前行上方打开一个新行并进入插入模式。
<hr /> 是您要插入的内容。
我们点击<CR> (<RETURN>) 来运行整个过程。
另一种方式,使用单个替换:
:%s/^\s*<h2/<hr \/>\r&<CR>
细分:
:%s[ubstitute]/ 对缓冲区的每一行执行替换,请参阅:h :s。
^ 将模式锚定到行首。
\s* 匹配任意数量(0 到多个)的空白字符。如果您确定所有 HTML 标记都在第 1 列上,则不需要这样做。
<h2 是我们真正在寻找的模式。
<hr /> 是我们要插入的内容。
由于我们希望它在自己的行上,它后面跟着一个\r,
最后是匹配的文本&。
【讨论】:
Perl 中的命令行解决方案。
perl -i~ -p -e'/<h2>/ and $_ = "<hr />\n$_"' your_file.html
命令行标志说明:
如果该行包含 (/<h2>/),则在其前面加上 <hr />(当前行在 $_ 中)。
但是您是否考虑过这是否是最好的方法?如果您想在每个 H2 元素上方添加一行,那么也许您应该使用 CSS 来做到这一点?
【讨论】:
perl -plne 'print "<hr />" if(/\<h2\>variable pattern here\<\/h2\>/)' your_file
输入文件:
> cat temp
<h2>variable pattern here</h2>
1
<h2>variable pattern here</h2>
2
<h2>variable pattern here</h2>
3
4
<h2>variable pattern here</h2>
现在执行
> perl -plne 'print "<hr />" if(/\<h2\>variable pattern here\<\/h2\>/)' temp
<hr />
<h2>variable pattern here</h2>
1
<hr />
<h2>variable pattern here</h2>
2
<hr />
<h2>variable pattern here</h2>
3
4
<hr />
<h2>variable pattern here</h2>
这只会输出到控制台。 如果你想就地改变它:
perl -pi -lne 'print "<hr />" if(/\<h2\>variable pattern here\<\/h2\>/)' your_file
【讨论】:
-p 和-n。你想在这里-p。而且我也看不到-l 在这里做任何有用的事情。此外,您的正则表达式比它需要的复杂得多:-/