相关:如何在(unix) shell脚本漂亮打印JSON ?
是否有(unix) shell脚本以人类可读的形式格式化XML ?
基本上,我想要它转换如下:
<root><foo a="b">lorem</foo><bar value="ipsum" /></root>
…变成这样:
<root>
<foo a="b">lorem</foo>
<bar value="ipsum" />
</root>
相关:如何在(unix) shell脚本漂亮打印JSON ?
是否有(unix) shell脚本以人类可读的形式格式化XML ?
基本上,我想要它转换如下:
<root><foo a="b">lorem</foo><bar value="ipsum" /></root>
…变成这样:
<root>
<foo a="b">lorem</foo>
<bar value="ipsum" />
</root>
当前回答
无需在macOS /大多数Unix上安装任何东西。
使用整洁
Cat filename.xml | tidy -xml -iq .xml
使用cat重定向查看文件,指定xml文件类型为tidy,并在安静输出时缩进,将抑制错误输出。JSON也可以使用-json。
其他回答
我想:
nicholas@mordor:~/flwor$
nicholas@mordor:~/flwor$ cat ugly.xml
<root><foo a="b">lorem</foo><bar value="ipsum" /></root>
nicholas@mordor:~/flwor$
nicholas@mordor:~/flwor$ basex
BaseX 9.0.1 [Standalone]
Try 'help' to get more information.
>
> create database pretty
Database 'pretty' created in 231.32 ms.
>
> open pretty
Database 'pretty' was opened in 0.05 ms.
>
> set parser xml
PARSER: xml
>
> add ugly.xml
Resource(s) added in 161.88 ms.
>
> xquery .
<root>
<foo a="b">lorem</foo>
<bar value="ipsum"/>
</root>
Query executed in 179.04 ms.
>
> exit
Have fun.
nicholas@mordor:~/flwor$
如果只是因为它“在”数据库中,而不“只是”一个文件。在我看来,更容易处理。
相信别人已经解决了这个问题。如果您愿意,毫无疑问eXist在格式化xml方面可能“更好”,或者同样好。
当然,您总是可以以各种不同的方式查询数据。我尽量让它简单。您也可以只使用GUI,但您指定了控制台。
yq可以用来打印XML。 它有一个定义缩进的选项。
yq --input-format xml --output-format xml --indent 2
你也可以使用tidy,它可能需要先安装(例如在Ubuntu上:sudo apt-get install tidy)。
为此,您可以发布如下内容:
tidy -xml -i your-file.xml > output.xml
注意:有许多额外的可读性标志,但是换行行为有点烦人(http://tidy.sourceforge.net/docs/quickref.html)。
这个简单的解决方案不提供缩进,但对人眼来说要容易得多。此外,它还允许使用grep、head、awk等简单工具更容易地处理xml。
使用sed将'<'替换为前面有换行符的自身。
正如Gilles所提到的,在生产中使用它可能不是一个好主意。
# check you are getting more than one line out
sed 's/</\n</g' sample.xml | wc -l
# check the output looks generally ok
sed 's/</\n</g' sample.xml | head
# capture the pretty xml in a different file
sed 's/</\n</g' sample.xml > prettySample.xml
编辑:
免责声明:您通常应该更喜欢安装像xmllint这样的成熟工具来完成这样的工作。XML/HTML可能是一团乱麻。但是,在某些情况下,使用现有工具比手动安装新工具更可取,而且可以肯定XML的源代码是有效的(足够有效)。我为其中一种情况编写了这个脚本,但这种情况很少见,所以请谨慎使用。
我想添加一个纯Bash解决方案,因为手动完成它并不“那么”困难,而且有时您不希望安装额外的工具来完成这项工作。
#!/bin/bash
declare -i currentIndent=0
declare -i nextIncrement=0
while read -r line ; do
currentIndent+=$nextIncrement
nextIncrement=0
if [[ "$line" == "</"* ]]; then # line contains a closer, just decrease the indent
currentIndent+=-1
else
dirtyStartTag="${line%%>*}"
dirtyTagName="${dirtyStartTag%% *}"
tagName="${dirtyTagName//</}"
# increase indent unless line contains closing tag or closes itself
if [[ ! "$line" =~ "</$tagName>" && ! "$line" == *"/>" ]]; then
nextIncrement+=1
fi
fi
# print with indent
printf "%*s%s" $(( $currentIndent * 2 )) # print spaces for the indent count
echo $line
done <<< "$(cat - | sed 's/></>\n</g')" # separate >< with a newline
将其粘贴到一个脚本文件中,并在xml中插入管道。 这假设xml都在一行上,并且任何地方都没有多余的空格。我们可以很容易地在正则表达式中添加一些额外的\s*来解决这个问题。