【问题标题】:Sed regexp multiline - replace HTMLSed 正则表达式多行 - 替换 HTML
【发布时间】:2012-06-18 02:12:39
【问题描述】:

我正在尝试在 Linux 系统上使用 sed 替换多行

这是我的文件

<!-- PAGE TAG -->
DATA1
DATA2
DATA3
DATA4
DATA5
DATA6
<div id="DATA"></div>
DATA8
DATA9
<!-- PAGE TAG -->

我的尝试都失败了!

sed -n '1h;1!H;${;g;s/<!-- PAGE TAG -->.*<!-- PAGE TAG -->//g;p;}' 
sed -n '1!N; s/<!-- PAGE TAG -->.*<!-- PAGE TAG -->// p'
sed -i 's|<!--[^>]*-->[^+]+<!--[^>]*-->||g' 
sed -i 's|/\/\/<!-- PAGE TA -->/,/\/\/<!-- PAGE TA -->||g'

&lt;!-- PAGE TAG --&gt; 之间的所有内容都应替换。

这个问题类似 sed multiline replace

【问题讨论】:

    标签: regex linux tags sed


    【解决方案1】:

    根据您看到的链接中给出的答案进行调整,这应该可以工作:

    sed '/<!-- PAGE TAG -->/,/<!-- PAGE TAG -->/d'
    

    正则表达式的格式是[2addr]d,其中两个地址是/&lt;!-- PAGE TAG --&gt;//&lt;!-- PAGE TAG --&gt;/,用逗号隔开。 d 表示删除从匹配第一个地址的行到匹配最后一个地址的行(含)的所有行。 (意思是标签之外的东西,但是和标签在同一行的东西也会被删除)。


    虽然 Tim Pote 已经回答了这个问题,但我还是把它贴在这里以防万一有人需要替换多行模式:

    sed -n '1h; 1!H; ${g; s/<!-- PAGE TAG -->[^!]*<!-- PAGE TAG -->//g; p;}'
    

    我从现有来源修改了解决方案,因此大部分命令都解释为here

    这里的正则表达式有点不完整,因为它假定两个页面标签之间的数据中没有! 字符。如果没有这个假设,我无法控制正则表达式匹配的字符数,因为没有惰性量词(据我所知)。

    此解决方案不会删除标签前的文本,即使它与标签在同一行。

    【讨论】:

    • 现在我做错了什么sed -i 's/&lt;!-- PAGE TAG --&gt;/,/&lt;!-- PAGE TAG --&gt;/Replace Data/g'
    • 我似乎无法对使用的文本运行 sed 替换。 sed 's/&lt;!-- PAGE TAG --&gt;\/,\/&lt;!-- PAGE TAG --&gt;/Data2/' /d 做什么?
    【解决方案2】:

    虽然@nhahtdh 的答案是您原始问题的正确答案,但此解决方案是您 cmets 的答案:

    sed '
      /<!-- PAGE TAG -->/,/<!-- PAGE TAG -->/ {
        1 {
          s/^.*$/Replace Data/
          b
        }
        d
      }
    '
    

    你可以这样读:

    /&lt;!-- PAGE TAG --&gt;/,/&lt;!-- PAGE TAG --&gt;/ -> 用于这些正则表达式之间的行

    1 { -> 第一个匹配行

    s/^.*$/Replace Data/ -> 搜索任何内容并替换为Replace Data

    b -> 分支到结束(在这种情况下表现得像中断)

    d -> 否则,删除该行

    您可以通过在每个命令后添加分号将任何一系列 sed 命令用 gnu sed 制作成单行(但如果您希望以后能够阅读,则不建议这样做):

    sed '/<!-- PAGE TAG -->/,/<!-- PAGE TAG -->/ { 1 { s/^.*$/Replace Data/; b; }; d; };'
    

    顺便说一句,您真的应该在您的帖子中尽可能具体。 “替换/删除”是指“替换或删除”。如果要更换,就说更换。这对我们这些试图回答您的问题的人以及可能遇到相同问题的未来用户都有帮助。

    【讨论】:

    • 非常感谢,这很好用。无论如何让它成为一个一个班轮
    • 谢谢@timpote,我已经更新了我的问题。感谢您的出色回答和解释,我不知道 sed 可以与 { 括号一起使用,看起来像条件​​ if 语句!我确实从您的回答中学到了很多东西。非常感谢!祝你有美好的一天。
    • @ChristopherWilson address { } 只是将命令分组以在特定的address 处运行。 branching 很难缠住你的脑袋。一旦你弄清楚了,你就可以认为自己是一个真正的 sed 高级用户 :) 快乐编码!
    • 跨多行的解决方案在 Mac 上运行良好,但单行解决方案似乎无法在 Mac 的 sed 上运行。似乎由于某种原因,分支命令在尝试搜索标签时尝试在行上消耗尽可能多的字符。
    • @nhahtdh 是的,就像我说的,我很确定分号是一个 gnu-sed 扩展。我很惊讶 BSD (read Mac) sed 完全解析了单行解决方案。我强烈建议在您的 Mac 上使用 MacPorts。 Gnu 工具通常比 BSD 工具更健壮且开发更积极。
    猜你喜欢
    • 2018-08-22
    • 1970-01-01
    • 2021-12-31
    • 2012-01-26
    • 1970-01-01
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多