我想要一个命令来从文件中删除 XML 页眉和页脚:
<?xml version="1.0" encoding="UTF-8"?>
<conxml>
<MsgPain001>
<HashValue>A9C72997C702A2F841B0EEEC3BD274DE1CB7BEA4B813E030D068CB853BCFECA6</HashValue>
<HashAlgorithm>SHA256</HashAlgorithm>
<Document>
...
</Document>
<Document>
...
</Document>
</MsgPain001>
</conxml>
...
应该变得只是
<Document>
...
</Document>
<Document>
...
</Document>
(注意缩进,第一个文档标签的缩进应该被删除。
这听起来像一个(贪婪的)正则表达式
<Document>.*</Document>
但由于换行,我没有得到它。
我需要它在管道中来计算所包含文档的哈希值。
答案1
使用sed
:
sed -n '/<Document>/,/<\/Document>/ p' yourfile.xml
解释:
-n
保持sed
沉默,这意味着它不会输出整个文件内容,/pattern/
搜索对于包含指定图案的线条,a
,
b
(逗号)告诉sed
执行行动a
在从到 的线路上b
(其中a
和b
通过匹配上述模式来定义),p
代表打印并且是行动在与上面匹配的行上执行。
编辑:如果您想额外去除之前的空格<Document>
,可以这样做:
sed -ne '/ <Document>/s/^ *//' -e '/<Document>/,/<\/Document>/ p' yourfile.xml
答案2
</Document>
为了防止文本在下一个文本之间被删除,<Document>
您可能必须使用一系列sed
命令(参见上面 Gilles 的评论)。
本质上是sed
将整个文件读入保留缓冲区(以便文件内容可以被视为一行)并标记第一个和最后一个Document
标签以供进一步处理。
# version 1
# marker: HERE
cat file.xml |
sed -n '1h;1!H;${;g;s/\(<Document>.*<\/Document>\)/HERE\1HERE/g;p;}' |
sed -n -e '/HERE<Document>/,/<\/Document>HERE/ p' |
sed -e 's/^ *HERE\(<Document>\)/\1/' -e 's/\(<\/Document>\)HERE *$/\1/'
# version 2 (using the Bash shell)
# marker: $'\001'
cat file.xml |
sed -n $'1h;1!H;${;g;s/\\(<Document>.*<\\/Document>\\)/\001\\1\001/g;p;}' |
sed -n -e $'/\001<Document>/,/<\\/Document>\001/ p' |
sed -e $'s/^ *\001//' -e $'s/\001 *$//' |
cat -vet
xmlstarlet
...但我想所有这一切都可以使用!来更优雅(且可靠)地完成。