在包含多个 XML 文件(可能有数百个文件)的目录中,我有一个名为<import_url>
.在此字段中,URL 可能包含下划线。
我希望将此下划线替换为连字符,如下例所示:
本质上
<import_url>archiv/in_natur/der-beitrag-name.html</import_url>
应该
<import_url>archiv/in-natur/der-beitrag-name.html</import_url>
如何在 Linux 命令行中搜索并替换它?
作为参考,这里是整个 XML 文件
<article id="6577889" type="article">
<author>
<forename>Hans</forename>
<surname>Wurs</surname>
<email>[email protected]</email>
<title></title>
<position></position>
<authorId>23262452</authorId>
</author>
<headline>Der Titel des Beitrags</headline>
<body>
Fringilla placerat elementum ratione? Illum blandit wisi adipisicing at sunt, proin minim. Quibusdam similique soluta, viverra
excepteur sem justo commodo? Congue eiusmod, temporibus doloribus urna pulvinar. Quibusdam elementum ante pretium nostra atque,
</body>
<date>
<createdDate>2020-04-30T10:44:35+00:00</createdDate>
<publishingDate>2020-04-30T00:00:00+00:00</publishingDate>
</date>
<metaDescription>Faucibus quidem quo, nostrud voluptates nunc mollitia curae</metaDescription>
<import_url>archiv/in_natur/der-beitrag-name.html</import_url>
<taxonomy type="channel">
<channel id="Archiv:Natur" parent="Archiv">Natur</channel>
</taxonomy>
</article>
答案1
如果您有格式正确的 XML 文档,则可以使用 XML 解析器/编辑器来修改它
源文件,/tmp/xml
<article>
<-- other sections omitted -->
<import_url>archiv/in_natur/der-beitrag-name.html</import_url>
</article>
修改
xmlstarlet edit --update '/article/import_url' --expr 'translate(., "_", "-")' /tmp/xml
输出
<?xml version="1.0"?>
<article>
<-- other sections omitted -->
<import_url>archiv/in-natur/der-beitrag-name.html</import_url>
</article>
由于匹配使用 XPath,//import_url
如果您愿意,您可以进行匹配。
--inplace
如果您确实想就地编辑文件,也可以添加。但我一般不建议这样做;最好写入临时文件,如果成功,则(并且只有此时)替换源。
答案2
与 xmlstarlet 解决方案类似,以下是使用 Saxon 的 Gizmo 实用程序执行此操作的方法:
java net.sf.saxon.Gizmo -s:/tmp/xml
/>update //import_url translate(., '_', '-')
/>save /tmp/xml
/>quit
https://saxonica.com/documentation/index.html#!gizmo
要处理目录中的所有文件,您可以运行此 XSLT 3.0 转换:
<xsl:transform version="3.0" expand-text="yes" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="import_url">
<xsl:copy>{translate(., '_', '-')}</xsl:copy>
</xsl:template>
<xsl:template name="xsl:initial-template">
<xsl:for-each select="collection('file:///my/input/directory?recurse=yes')">
<xsl:result-document href="file:///my/output/directory/{tokenize(document-uri(),'/')[last()]}">
<xsl:apply-templates/>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:transform>