Sed regexp multiline - 替换HTML

时间:2012-06-15 00:59:42

标签: regex linux tags sed

我试图在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'

应更换<!-- PAGE TAG -->之间的所有内容。

这个问题很相似 sed multiline replace

2 个答案:

答案 0 :(得分:4)

根据您看到的链接中给出的答案进行调整,这应该有效:

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

正则表达式的格式为[2addr]d,其中2个地址为/<!-- PAGE TAG -->//<!-- PAGE TAG -->/,以逗号分隔。 d表示将从第一个地址匹配的行中的所有行删除到与最后一个地址匹配的行。 (它表示标记之外的内容,但与标记位于同一行也将被删除)。


虽然蒂姆波特回答了这个问题,但我会在这里发布,以防有​​人需要更换多线模式:

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

我修改了现有源代码的解决方案,因此解释了大部分命令here

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

此解决方案不会删除标记之前的文本,即使它与标记位于同一行。

答案 1 :(得分:3)

虽然@nhahtdh的回答是原始问题的正确答案,但这个解决方案是您的意见的答案:

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

您可以这样阅读:

/<!-- PAGE TAG -->/,/<!-- PAGE TAG -->/ - &gt;这些正则表达式之间的界限

1 { - &gt;对于第一个匹配的行

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

b - &gt;分支结束(在这种情况下表现得像破坏)

d - &gt;否则,删除行

你可以通过在每个命令之后添加分号来将任何系列的sed命令变成带有gnu sed的单行(但是如果你想稍后能够阅读它,则不建议这样做):

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

作为旁注,您应该尽量在发布中尽可能具体。 “替换/删除”表示“替换或删除”。如果你想要它被替换,只需说替换。这有助于我们这些尝试回答您问题的人以及可能遇到同样问题的未来用户。