【问题标题】:Replacing multiline string between two patterns with sed用 sed 替换两个模式之间的多行字符串
【发布时间】:2016-06-29 20:36:02
【问题描述】:

我有一个文件在 xml 标签之间保存了一个长的单行字符串,我想用 sed 替换标签之间的内容。

1300_character_long_string_here

我遇到的问题是 sed 没有替换,尽管我知道我的正则表达式选择正确。也就是说,即使我能够正确选择和替换,我也不知道如何从文件中提取替换字符串(大致一样长)并放置它。

这是我目前在命令中比较成功的尝试之一:

sed 's/\<Tag\>(.*)\<\/Tag\>/REPLACE/g' test.txt> out.txt

虽然这不起作用,但如果我尝试仅替换第一个标签,我可以看到它正在替换。

我应该在一开始就提到这是一个 AIX 系统,而不是一个 GNU 系统。

【问题讨论】:

  • 你试过's#\&lt;Tag\&gt;(.*)\&lt;\/Tag\&gt;#REPLACE#g'吗?
  • 搜索 replace multiline string [sed] 会返回 14 个 Q/As。你看过这些答案了吗?你几乎肯定会找到一些好的建议。祝你好运。
  • 正则表达式不适合修改xml文档
  • @Beta 我有,没有变化。

标签: xml shell


【解决方案1】:

您可以使用 rcommand 从文件中插入替换文本:

sed '
/<Tag>.*<\/Tag>/{
r newcontentfile
d
}
' file

并且不要转义标签中的&lt;&gt;,因为它用于word boundaries。它可以解释为什么您的模式不匹配。

【讨论】:

  • 对。 @KeigaTide 您必须了解转义对每个角色的影响。当您转义元字符(例如*)时,它会变成文字,但是当您转义某些 sed 中的 some 文字字符时,它们会变成元字符(例如 + 或在本例中为 &lt; &gt; 成为 GNU sed 中的单词边界)。如果您不确定,请使用[] 封装一个字符(例如[&lt;]),以确保您在需要时将元字符转换为文字,但不会意外地将文字转换为元字符)。
  • @Kenavoz 正如我所写的 sed 版本无法解析您的解决方案,我会戳它。单词边界是我不知道的,谢谢。也就是说,删除转义字符会导致正则表达式选择整个字符串。
  • @KeigaTide 模式中的() 必须用于反向引用(在基本正则表达式模式下,您必须将其转义为\(\))。它不仅会匹配&lt;Tag&gt; 的内容,还会匹配整个字符串。
  • @Kenavoz 转义括号,不转义它们并完全删除它们都会匹配整个字符串。他们不是问题。
【解决方案2】:

我建议是这样的:

File1 包含替换文本,例如

some other string

File2 包含标记行:

...
<tag>some string</tag>
...

现在,你可以说:

sed '1{h;d}; /<tag>/{x;s/^/<tag>/;s/$/<\/tag>/}' File1 File2

这是如何工作的:首先,读取替换文件,将其单行放在保持空间中,然后将其从输出流中删除。接下来,如果一行匹配&lt;tag&gt;,则从保留空间中检索替换文本,并添加标签。

【讨论】:

    猜你喜欢
    • 2016-03-22
    • 1970-01-01
    • 2022-10-24
    • 2023-02-04
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    相关资源
    最近更新 更多