Найдите конкретный тег xml и замените текст внутри тегов некоторым параметризованным значением. Необходимо заменить несколько вхождений.
Пример содержимого файла:
<a>abc</a>
Текущая попытка:
sed -i "s/\(<a>\).*\(<\/a>\)/\(<a>\)$param\(<\/a>\)/g" script.xml
Желаемый результат: если param=111, то
<a>111</a>
Я бы сделал это в Perl вместо sed
, так как Perl поддерживает не -жадные совпадения:
perl -i -pe "s|<a>.+?</a>|<a>$param</a>|g" file
.+?
означает «сопоставить кратчайшую возможную строку», поэтому будет найдена кратчайшая строка между <a>
и </a>
.
Однако я должен подчеркнуть, что это, скорее всего, не удастся даже с немного сложными XML-документами, и вам действительно следует рассмотреть возможность использования вместо этого специализированного синтаксического анализатора XML.
Я знаю, что вы просили sed
решение, но обычно я рекомендую инструмент на основе XML -, (которого есть число )вместо sed
при работе с XML-документом, отличным от очень простой.
Предположим, это мой XML-документ(doc.xml
):
<?xml version="1.0"?>
<xml>
<c><a>abc</a></c>
<b>
<a>abc</a>
<a>abc</a>
</b>
<a parm="FPM">abc</a>
</xml>
Я собираюсь использовать следующую таблицу стилей XML, style.xsl
, чтобы преобразовать документ в желаемый формат.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name = "value" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a/text()[.='abc']">
<xsl:value-of select = "$value" />
</xsl:template>
</xsl:stylesheet>
Я использую инструмент xsltproc
, который по умолчанию установлен в большинстве основных дистрибутивов Linux, для выполнения преобразования:
$ xsltproc --stringparam value "111" style.xsl doc.xml
<?xml version="1.0"?>
<xml>
<c><a>111</a></c>
<b>
<a>111</a>
<a>111</a>
</b>
<a parm="FPM">111</a>
</xml>
$