使用sed将特定标签后的单词替换为括号

时间:2018-05-09 08:55:18

标签: xml macos sed

我有一个由BLAST 2.5.0+生成的xml文件。我希望做一些改变。具体来说,我希望将OS =在我的文件中的所有单词放在[]中。我的原始文件格式如下: -

<Hit_num>1</Hit_num>
<Hit_id>TR:V4U0L5_9ROSI</Hit_id>
<Hit_def>gnl|V4U0L5| Uncharacterized protein OS=Homo sapien
OX=393305 GN=CICLE_v10008136mg PE=4 SV=1</Hit_def>
<Hit_accession>TR:V4U0L5_9ROSI</Hit_accession>
<Hit_len>388</Hit_len>

使用以下CMD: - sed -E 's/<Hit_def>(.*)OS=([A-Za-z\.\-\,\_ ]+)(( [A-Z]+=.*))<\/Hit_def>/<Hit_def>\1[\2]\3<\/Hit_def>/g' input.xml > output.xml,我设法得到以下内容: -

<Hit_num>1</Hit_num>
<Hit_id>TR:V4U0L5_9ROSI</Hit_id>
<Hit_def>gnl|V4U0L5| Uncharacterized protein [Homo sapien]
OX=393305 GN=CICLE_v10008136mg PE=4 SV=1</Hit_def>
<Hit_accession>TR:V4U0L5_9ROSI</Hit_accession>
<Hit_len>388</Hit_len>

然而,OS之后的一些词语=具有不同的特征。例如: -

<Hit_num>1</Hit_num>
<Hit_id>TR:V4U0L5_9ROSI</Hit_id>
<Hit_def>gnl|V4U0L5| Uncharacterized protein OS=Yersinia enterocolitica serotype O:8 / biotype 1B (strain NCTC 13174 / 8081)
OX=393305 GN=CICLE_v10008136mg PE=4 SV=1</Hit_def>
<Hit_accession>TR:V4U0L5_9ROSI</Hit_accession>
<Hit_len>388</Hit_len>

使用上面的相同CMD,这些单词根本不会放在[]内。通过使用Mac OS X,我可以做什么来在OS =进入[]之后将一切包括在内?

1 个答案:

答案 0 :(得分:1)

使用xslt,您可以比sed更强大,更强大的方式轻松操作XML文件:

<强> INPUT:

<?xml version="1.0"?>
<Hit>
        <Hit_num>1</Hit_num>
        <Hit_id>TR:V4U0L5_9ROSI</Hit_id>
        <Hit_def>gnl|V4U0L5| Uncharacterized protein OS=Homo sapien OX=393305 GN=CICLE_v10008136mg PE=4 SV=1</Hit_def>
        <Hit_accession>TR:V4U0L5_9ROSI</Hit_accession>
        <Hit_len>388</Hit_len>
</Hit>

<强>样式表:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:redirect="http://xml.apache.org/xalan/redirect" extension-element-prefixes="redirect" xmlns:xalan="http://xml.apache.org/xslt" exclude-result-prefixes="xalan">
<xsl:output method="xml" indent="yes" xalan:indent-amount="4"/>
<xsl:strip-space elements="*" />

<xsl:template match="node() | @*">
        <xsl:copy>
                <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
</xsl:template>

    <xsl:template match="//Hit_def">
        <xsl:variable name="stringToReplace" select="."/>
        <Hit_def><xsl:value-of select="replace($stringToReplace,'OS=([^=]*)\s+OX=','[$1] OX=')"/></Hit_def>
    </xsl:template>
</xsl:stylesheet>

<强>输出:

$ java -jar saxon9he.jar -s:hit.xml -xsl:hit.xsl
<?xml version="1.0" encoding="UTF-8"?>
<Hit>
   <Hit_num>1</Hit_num>
   <Hit_id>TR:V4U0L5_9ROSI</Hit_id>
   <Hit_def>gnl|V4U0L5| Uncharacterized protein [Homo sapien] OX=393305 GN=CICLE_v10008136mg PE=4 SV=1</Hit_def>
   <Hit_accession>TR:V4U0L5_9ROSI</Hit_accession>
   <Hit_len>388</Hit_len>
</Hit>

如果您需要saxon9he.jar,请从http://saxon.sourceforge.net/获取 您也可以在系统上使用xsltproc或其他命令。

最后但并非最不重要的一点是,您可能需要修剪反向引用以避免[Home Sapien ]之类的结果。如有必要,您可以使用以下stylesheet

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:redirect="http://xml.apache.org/xalan/redirect" extension-element-prefixes="redirect" xmlns:xalan="http://xml.apache.org/xslt" exclude-result-prefixes="xalan">
<xsl:output method="xml" indent="yes" xalan:indent-amount="4"/>
<xsl:strip-space elements="*" />

<xsl:template match="node() | @*">
        <xsl:copy>
                <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
</xsl:template>

    <xsl:template match="//Hit_def">
        <xsl:variable name="stringToReplace" select="."/>
        <xsl:variable name="stringTmp" select="replace($stringToReplace,'OS=([^=]*)\s+OX=','[$1] OX=')"/>
        <Hit_def><xsl:value-of select="replace($stringTmp,'\s+\]\s+OX=','] OX=')"/></Hit_def>
    </xsl:template>
</xsl:stylesheet>