sha*_*455 4 unix linux shell awk
我有一个带有标签的 XML 文件。我想像这样拆分文件。
<?xml version="1.0" encoding="UTF-8"?>
<EMPRMART CREATION_DATE="08/20/2018 18:06:44" REPOSITORY_VERSION="187.96">
<REPOSITORY NAME="REP_DEV" VERSION="187" CODEPAGE="UTF-8" DATABASETYPE="Sybase">
<FOLDER NAME="MC_DEV"
<CONFIG DESCRIPTION ="Default ORDER configuration object" ISDEFAULT ="YES" NAME ="default_ORDER_config" VERSIONNUMBER ="1">
<ATTRIBUTE NAME ="Advanced" VALUE =""/>
<ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
</CONFIG>
<ORDER DESCRIPTION ="" ISVALID ="YES"
<ATTRIBUTE NAME ="Normal" VALUE =""/>
<ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
</ORDER>
<ORDER DESCRIPTION ="" ISVALID ="YES"
<ATTRIBUTE NAME ="Medium" VALUE =""/>
<ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
</ORDER>
<ORDER DESCRIPTION ="" ISVALID ="YES"
<ATTRIBUTE NAME ="Advanced" VALUE =""/>
<ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
</ORDER>
<LOCATION DESCRIPTION ="" ISENABLED ="YES"
</LOCATION>
</FOLDER>
</REPOSITORY>
</EMPRMART>
Run Code Online (Sandbox Code Playgroud)
下面是尝试的代码。但它正在将每一行生成到一个新文件中
awk '
BEGIN { RS = "</ORDER>" }
$0 ~ /[^[:blank:]\n]/ {
printf "%s\n", $0 RS >> FILENAME "_" ++i ".xml"
}
' test.xml
Run Code Online (Sandbox Code Playgroud)
我想单独根据 ORDER 标签拆分此文件,如下所述
File1.xml
<ORDER DESCRIPTION ="" ISVALID ="YES"
<ATTRIBUTE NAME ="Normal" VALUE =""/>
<ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
</ORDER>
File2.xml
<ORDER DESCRIPTION ="" ISVALID ="YES"
<ATTRIBUTE NAME ="Medium" VALUE =""/>
<ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
</ORDER>
File3.xml
<ORDER DESCRIPTION ="" ISVALID ="YES"
<ATTRIBUTE NAME ="Advanced" VALUE =""/>
<ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
</ORDER>
Run Code Online (Sandbox Code Playgroud)
为了实现您的要求,我不会使用 awk,而是使用一个好的 XML 解析器,例如 xmlstarlet 或 xmlint。这里有一个未知数,即名称为 的节点总数ORDER
。我们可以为选择写下一个高级 XPath,但我们会保持简单:
xmlstarlet sel -t -v 'count(//ORDER)' file.xml
Run Code Online (Sandbox Code Playgroud)
现在您有了计数,您可以遍历所有案例并将它们写入文件:
#!/usr/bin/env bash
xmlfile=file.xml
n=$(xmlstarlet sel -t -v 'count(//ORDER)' file.xml)
for i in $(seq 1 $n); do
xmlstarlet sel -t -m "//ORDER[${i}]" -c . $xmlfile > "File${i}.xml"
done
Run Code Online (Sandbox Code Playgroud)
如果你确实使用gnu awk
它应该给出你要求的结果。
awk '/<ORDER>/ {f=1;++a} f {print > "file_"a".xml"} /<\/ORDER>/ {f=0}' file
Run Code Online (Sandbox Code Playgroud)
它将从只打印线<ORDER>
,以</ORDER>
作为调用文件的一部分file_1.xml
,file_2.xml
等等。
在每个 UNIX 机器上的任何 shell 中使用任何 awk:
awk '/<ORDER/{f=1; out="file_"(++c)".xml"} f{print > out} /<\/ORDER>/{close(out); f=0}' file
Run Code Online (Sandbox Code Playgroud)
它显然很脆弱,因为它只是对文本进行正则表达式匹配,而不是解析 XML,但它适用于您发布的示例和任何类似的文本。