【问题标题】:Find and replace in file with script用脚本在文件中查找和替换
【发布时间】:2014-07-02 12:55:21
【问题描述】:

我想查找 VALUE 并将其替换为 xml 文件:

<test name="NAME" value="VALUE"/>

我必须按名称过滤(因为有很多这样的行)。

有可能吗?

感谢您的帮助。

【问题讨论】:

  • 您想用 VALUE 替换吗?
  • sed -i 's~VALUE~foo~g' file.xml
  • 值是一个随机值,比如我设置了VALUE,但它是一个字符串,必须用其他字符串替换。
  • 所以它会在 value= 字段之后。
  • 是的,我必须按名称过滤。

标签: bash


【解决方案1】:

由于您将问题标记为“bash”,因此我假设您没有尝试使用 XML 库(尽管我认为 XML 专家可能能够为您提供类似于 XSLT 处理器命令的东西,可以非常稳健地解决这个问题),但您只是对从命令行进行搜索和替换感兴趣。

我为此使用 perl:

perl -pi -e 's#VALUE#replacement#g' *.xml

参见perlrun 手册页:简而言之,-p 将 perl 切换到文本处理模式,-i 代表“就地”,-e 让我们指定一个表达式以应用于所有行输入。

另外请注意(如果您还不太熟悉的话)您可以使用除# 之外的其他字符(常见的是%、逗号等),这些字符不会与您的搜索和替换发生冲突字符串。

有一个小警告:perl 将读取和写入命令行中给出的所有文件,即使是那些没有改变的文件。因此,即使文件没有更改,文件的修改时间也会更新。 (我通常使用更多的 shell 魔法来解决这个问题,例如使用 grep -lgrin -l 来选择文件供 perl 处理。)

编辑:如果我正确理解您的 cmets,您还需要有关正则表达式的帮助才能应用。让我简要地提出这样的建议:

perl -pi -e 's,(name="NAME" value=)"[^"]*",\1"NEWVALUE",g' *.xml

【讨论】:

  • 我不知道 VALUE,它是一个字符串,在我的帖子中替换为“VALUE”。而且,我必须按名称过滤。
  • 如果你知道name=总是在value=之前,那么只需在上面的命令中扩展正则表达式即可。如果你不这样做,我会用“xml”标记问题并使用适当的 XML 工具来完成这项工作。
  • 是的,名字总是在值之前;)
  • 好的,我已经更新了我的答案,还使用了 \1 以避免在替换字符串中重复过多的搜索字符串。希望这会有所帮助,即使我对仅使用字符串处理来处理非平凡的 XML 感到不舒服。 ;-)
  • 太好了,太完美了。
【解决方案2】:

相关:bash XHTML parsing using xpath

你可以使用SED:

SED 's/\(<test name=\"NAME\"\) value=\"VALUE\"/\1 value=\"YourValue\"/' test.xml

其中 test.xml 是包含给定节点的 xml 文档。这是非常脆弱的,如果您需要多次执行此替换,您可以努力使其更加灵活。例如,当前语句区分大小写,因此它不会将节点上的值替换为 name="name",但您可以在语句末尾添加不区分大小写标志,如下所示:

('s/\(&lt;test name=\"NAME\"\) value=\"VALUE\"/\1 value=\"YourValue\"/I')

另一种选择是使用XSLT,但这需要您下载外部库。它非常通用,并且可能是对 XML 文档进行更复杂修改的可行选项。

【讨论】:

    猜你喜欢
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    • 2012-06-07
    • 2013-05-26
    • 2019-07-30
    • 2019-10-16
    相关资源
    最近更新 更多