Bash - 在文件中搜索特定字符串并替换为直接源

Rus*_*sso 2 bash awk sed xmlstarlet

我试图在包含以下内容的文件中搜索字符串"missing":

<message>
    <source>TypeA</source>
    <translation>missing</translation>
</message>
<message>
    <source>TypeB</source>
    <translation>missing</translation>
</message>
<message>
    <source>TypeC</source>
    <comment>Context menu</comment>
    <translation>missing</translation>
</message>
Run Code Online (Sandbox Code Playgroud)

如果找到"缺失",我想用它的直接源名称替换字符串.例如:

<message>
    <source>TypeA</source>
    <translation>TypeA</translation>
</message>
<message>
    <source>TypeB</source>
    <translation>TypeB</translation>
</message>
<message>
    <source>TypeC</source>
    <comment>Context menu</comment>
    <translation>TypeC</translation>
</message>
Run Code Online (Sandbox Code Playgroud)

到目前为止,我能够使用awk搜索字符串并打印直接源名称:

match($0, /<source>(.*)<\/source>/,n){ src=n[1] }
match($0, /<translation>(.*)<\/translation>/,s){ trs=s[1] }
/unfinished/{ print "Translation missing or incomplete for: '" trs "'","located inside source named: '" src "'" }
Run Code Online (Sandbox Code Playgroud)

然后将其保存为something.awk使用以下方式调用:

awk -f something.awk filelocation
Run Code Online (Sandbox Code Playgroud)

但我不知道如何用源中的值替换字符串"missing".

任何人都可以建议我如何更换它?

Ken*_*ent 5

即使你已经接受了答案,我也会加上这个.

在您的评论中,您告诉我们您的输入文件是格式正确的xml文档.所以我会以xml方式处理它.我喜欢awk/sed/grep,但我不得不说他们(和正则表达式)真的不是处理xml文件的正确工具,尽管它有时会很快而且很脏.

有命令行工具:xsltproc,可以通过xslt将xml文档转换为其他格式.

xslt也相对简单:(保存为f.xslt)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="translation[.='missing']">
        <xsl:copy>
            <xsl:value-of select="../source"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

你需要做的只是:

xsltproc f.xslt input.xml
Run Code Online (Sandbox Code Playgroud)

用输入文件测试一下:( 我添加了一个根元素)

kent$  cat f.xml
<root>
        <message>
                <source>TypeA</source>
                <translation>missing</translation>
        </message>
        <message>
                <source>TypeB</source>
                <translation>missing</translation>
        </message>
        <message>
                <source>TypeC</source>
                <comment>Context menu</comment>
                <translation>missing</translation>
        </message>
</root>

kent$  xsltproc f.xslt f.xml
<?xml version="1.0"?>
<root>
        <message>
                <source>TypeA</source>
                <translation>TypeA</translation>
        </message>
        <message>
                <source>TypeB</source>
                <translation>TypeB</translation>
        </message>
        <message>
                <source>TypeC</source>
                <comment>Context menu</comment>
                <translation>TypeC</translation>
        </message>
</root>
Run Code Online (Sandbox Code Playgroud)

只要您的输入xml格式正确,这将始终有效.即使您输入xml在一行或其他格式中也没关系.