【问题标题】:How do I insert a line above specific lines in a file using Vim or Perl?如何使用 Vim 或 Perl 在文件中的特定行上方插入一行?
【发布时间】:2012-12-29 09:02:25
【问题描述】:

我想插入一行

<hr />

在文件中每次出现的标题 2 行之上 - 例如,在此模式之上

<h2>variable pattern here</h2>

所以上面应该变成

<hr />
<h2>variable pattern here</h2>

如何使用 Vim、Sed 或 Perl 做到这一点?

【问题讨论】:

  • 你自己有没有尝试过?

标签: regex perl vim sed


【解决方案1】:

使用sed,您可以使用sed '/&lt;h2&gt;/i &lt;hr /&gt;'

$ 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>

第一部分/&lt;h2&gt;/ 匹配包含&lt;h2&gt; 的行,第二部分使用i 命令在匹配行上方插入&lt;hr /&gt;

sed 的一个不错的选项是-i,这会将更改保存回文件而不是打印到stdout,但首先要确保更改正确。

sed -i '/<h2>/i <hr />' file

【讨论】:

  • 您能否解释一下它是如何工作的,即/i 的作用?
  • @sudo_O 效果很好。谢谢楼主!
  • 可以,但要再等6分钟
【解决方案2】:
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;

【讨论】:

    【解决方案3】:

    vim方式:

    cmd :g/&lt;h2&gt;/normal O&lt;hr /&gt; 将完成这项工作。

    在这里看到它:(我从 sudo_O 中拿了例子)

    【讨论】:

      【解决方案4】:

      在 Vim 中执行此操作的众多方法之一:

      :g/h2/norm O<hr /><CR>
      

      细分:

      1. :g[lobal] 作用于与模式匹配的每一行,参见:h :global

      2. h2 我们正在寻找的模式,它可能会变得更智能一些。

      3. norm[al] 运行正常模式命令,参见:h :normal

      4. O 在当前行上方打开一个新行并进入插入模式。

      5. &lt;hr /&gt; 是您要插入的内容。

      6. 我们点击&lt;CR&gt; (&lt;RETURN&gt;) 来运行整个过程。

      另一种方式,使用单个替换:

      :%s/^\s*<h2/<hr \/>\r&<CR>
      

      细分:

      1. :%s[ubstitute]/ 对缓冲区的每一行执行替换,请参阅:h :s

      2. ^ 将模式锚定到行首。

      3. \s* 匹配任意数量(0 到多个)的空白字符。如果您确定所有 HTML 标记都在第 1 列上,则不需要这样做。

      4. &lt;h2 是我们真正在寻找的模式。

      5. &lt;hr /&gt; 是我们要插入的内容。

      6. 由于我们希望它在自己的行上,它后面跟着一个\r

      7. 最后是匹配的文本&amp;

      【讨论】:

        【解决方案5】:

        Perl 中的命令行解决方案。

        perl -i~ -p -e'/<h2>/ and $_ = "<hr />\n$_"' your_file.html
        

        命令行标志说明:

        • -i就地编辑(替换现有文件),备份到your_file.html~
        • -p 打印文件中的每一行
        • -e 为文件中的每一行执行的代码

        如果该行包含 (/&lt;h2&gt;/),则在其前面加上 &lt;hr /&gt;(当前行在 $_ 中)。

        但是您是否考虑过这是否是最好的方法?如果您想在每个 H2 元素上方添加一行,那么也许您应该使用 CSS 来做到这一点?

        【讨论】:

          【解决方案6】:
          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 在这里做任何有用的事情。此外,您的正则表达式比它需要的复杂得多:-/
          猜你喜欢
          • 1970-01-01
          • 2010-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-26
          相关资源
          最近更新 更多