У меня есть XML-файл, что я хочу настроить использование сценария удара. Например, если у меня был этот xml:
<a>
<b>
<bb>
<yyy>
Bla
</yyy>
</bb>
</b>
<c>
<cc>
Something
</cc>
</c>
<d>
bla
</d>
</a>
(конфиденциальная информация удалила),
Я хотел бы записать сценарий удара, который удалит раздел <b>
(или прокомментируйте это), но сохраните остальную часть xml неповрежденного. Я довольно новый целая вещь сценариев. Я задавался вопросом, мог ли кто-либо дать мне подсказку относительно того, что я должен изучить.
Я думал, что sed мог использоваться кроме sed, строчный редактор. Я думаю, что было бы легко удалить <b>
теги однако, я не уверен, если sed смог бы удалить весь текст между <b>
теги.
Я должен буду также записать сценарий для добавления назад удаленного раздела.
Это не составит труда сделать в sed, поскольку sed также работает с диапазонами.
Попробуйте это (при условии, что xml находится в файле с именем foo.xml):
sed -i '/<b>/,/<\/b>/d' foo.xml
-i запишет изменение в исходный файл (используйте -i.bak, чтобы сохранить резервную копию оригинала)
Эта команда sed выполнит действие d (удалить) во всех строках заданный диапазоном
# all of the lines between a line that matches <b>
# and the next line that matches <\/b>, inclusive
/<b>/,/<\/b>/
Таким образом, на простом английском языке эта команда удалит все строки между строкой с и строкой с
включительно. Если вы предпочитаете закомментировать строки попробуйте один из следующих вариантов:
# block comment
sed -i 's/<b>/<!-- <b>/; s/<\/b>/<\/b> -->/' foo.xml
# comment out every line in the range
sed -i '/<b>/,/<\/b>/s/.*/<!-- & -->/' foo.xml
Если вам нужна наиболее подходящая замена для sed
для данных XML, то это будет процессор XSLT. Как и sed
, это сложный язык, но он специализируется на задачах преобразования XML во что-либо.
С другой стороны, это действительно кажется точкой, в которой я бы серьезно подумал о переходе на настоящий язык программирования, такой как Python.
Вы можете использовать XSLT, подобный этому, который является преобразованием модифицированной идентичности. Он копирует все содержимое по умолчанию и имеет пустой шаблон для b
, который ничего не делает (фактически удаляет из вывода):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--Identity transform copies all items by default -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--Empty template to match on b elements and prevent it from being copied to output -->
<xsl:template match="b"/>
</xsl:stylesheet>
Создайте сценарий bash, который выполняет преобразование с использованием Java и Утилита командной строки Xalan выглядит так:
java org.apache.xalan.xslt.Process -IN foo.xml -XSL foo.xsl -OUT foo.out
Результат следующий:
<?xml version="1.0" encoding="UTF-16"?><a><c><cc>
Something
</cc></c><d>
bla
</d></a>
РЕДАКТИРОВАТЬ: , если вы предпочитаете, чтобы b
закомментировали, чтобы упростить возврат, используйте эту таблицу стилей:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--Identity transform copies all items by default -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--Match on b element, wrap in a comment and construct text representing XML structure by applying templates in "comment" mode -->
<xsl:template match="b">
<xsl:comment>
<xsl:apply-templates select="self::*" mode="comment" />
</xsl:comment>
</xsl:template>
<xsl:template match="*" mode="comment">
<xsl:value-of select="'<'"/>
<xsl:value-of select="name()"/>
<xsl:value-of select="'>'"/>
<xsl:apply-templates select="@*|node()" mode="comment" />
<xsl:value-of select="'</'"/>
<xsl:value-of select="name()"/>
<xsl:value-of select="'>'"/>
</xsl:template>
<xsl:template match="text()" mode="comment">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="@*" mode="comment">
<xsl:value-of select="name()"/>
<xsl:text>="</xsl:text>
<xsl:value-of select="."/>
<xsl:text>" </xsl:text>
</xsl:template>
</xsl:stylesheet>
Результат будет следующим:
<?xml version="1.0" encoding="UTF-16"?><a><!--<b><bb><yyy>
Bla
</yyy></bb></b>--><c><cc>
Something
</cc></c><d>
bla
</d></a>
@OP, вы можете использовать awk, например,
$ cat file
<a>
some text before <b>
<bb>
<yyy>
Bla
</yyy>
</bb>
</b> some text after
<c>
<cc>
Something
</cc>
</c>
<d>
bla
</d>
</a>
$ awk 'BEGIN{RS="</b>"}/<b>/{gsub(/<b>.*/,"")}1' file
<a>
some text before
some text after
<c>
<cc>
Something
</cc>
</c>
<d>
bla
</d>
</a>
Использование xmlstarlet:
#xmlstarlet ed -d "/a/b" file.xml > tmp.xml
xmlstarlet ed -d "//b" file.xml > tmp.xml
mv tmp.xml file.xml
# edit file inplace
xmlstarlet ed -L -d "//b" file.xml