首页 > 解决方案 > 使用 sed 换行。sed 不一致或者我犯了一个大错误

问题描述

编辑这张票不是关于解析 XML 的。请在跳马前阅读问题。先感谢您。

curl 调用在一行中将文本(在此示例中为 xml)发回给我。出于可读性目的,我将其转换为 shell 以用于我自己的目的,因此它在每个节点的开头换行:

cat xml | sed 's/</\n</g'

它工作得很好:

$ echo "<div><b>test</b><b>an other text</b></div>" | sed 's/</\n</g'

<div>
<b>test
</b>
<b>an other text
</b>
</div>

但是,我想在结束标记之后>且仅在结束标记中换行。
我创建了这个sed看起来很划算的表达式:

$ echo "<div><b>test</b><b>an other text</b></div>" | sed -E 's/<\/(.?)>/<\/\1>\n/g'
<div><b>test</b>
<b>an other text</b>
</div>

但是它不适用于此:

$ echo "<file><atime>1559521691000</atime><id>CE0E7BAD4FD4409B2AFBC7895482C296896BF947</id><ctime>1470853372000</ctime><factor>290204195029359</factor></file>" | sed -E 's/<\/(.?)>/<\/\1>\n/g'
<file><atime>1559521691000</atime><id>CE0E7BAD4FD4409B2AFBC7895482C296896BF947</id><ctime>1470853372000</ctime><factor>290204195029359</factor></file>

知道为什么吗?!

我看不出有什么理由会被拒绝。我看不出这个和上一个之间有任何普遍的区别。我很高兴听到没有办法sed做到这一点,但我想知道为什么它适用于第一个示例而不适用于第二个示例。

有没有好的灵魂可以启发我?我有自己的程序可以为我执行此操作,但我想在只能编写脚本的生产服务器上执行此命令。

标签: xmlbashsedformat

解决方案


搜索模式<\/(.?)>匹配任何一个字符</></X>其中X的任何字符。即,具有空名称或单字母名称的结束标记。

在您的第一个示例(它“工作”的地方)中,您会看到</b>与该模式匹配的中断。

在您的第二个示例中,没有带有空名称或单字母名称的结束标签。您需要调整模式。考虑例如:<\/([^>]*)>


推荐阅读