我正在尝试将一个大型xml文件拆分为多个文件,并在AWK脚本中使用了以下代码。
/<fileItem>/ { rfile="fileItem" count ".xml" print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" > rfile print $0 > rfile getline while ($0 !~ "<\/fileItem>" ) { print > rfile getline } print $0 > rfile close(rfile) count++ }
上面的代码生成一个名称为“ fileItem_1”,“ fileItem_2”,“ fileItem3”等的xml文件列表。
但是,我希望文件名类似于“ item_XXXXX”,其中XXXXX是XML内的一个节点-如下图所示
<fileItem> <id>12345</id> <name>XXXXX</name> </fileItem>
因此,基本上我希望“ id”节点为文件名。谁能帮我这个忙吗?
我不会用getline。(我什至在AWK书中读到,不建议使用它。)我认为,使用全局变量进行状态处理甚至更简单。(带有全局变量的表达式也可以在模式中使用。)
getline
该脚本可能如下所示:
test-split-xml.awk:
test-split-xml.awk
/<fileItem>/ { collect = 1 ; buffer = "" ; file = "fileItem_"count".xml" ++count } collect > 0 { if (buffer != "") buffer = buffer"\n" buffer = buffer $0 } collect > 0 && /<name>.+<\/name>/ { # cut "...<name>" i = index($0, "<name>") ; file = substr($0, i + 6) # cut "</name>..." i = index(file, "</name>") ; file = substr(file, 1, i - 1) file = file".xml" } /<\/fileItem>/ { collect = 0; print file print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" >file print buffer >file }
我准备了一些样本数据进行小型测试:
test-split-xml.xml:
test-split-xml.xml
<?xml version=\"1.0\" encoding=\"UTF-8\"?> <top> <some> <fileItem> <id>1</id> <name>X1</name> </fileItem> </some> <fileItem> <id>2</id> <name>X2</name> </fileItem> <fileItem> <id>2</id> <!--name>X2</name--> </fileItem> <any> other input </any> </top>
…并获得以下输出:
$ awk -f test-split-xml.awk test-split-xml.xml X1.xml X2.xml fileItem_2.xml $ more X1.xml <?xml version="1.0" encoding="UTF-8"?> <fileItem> <id>1</id> <name>X1</name> </fileItem> $ more X2.xml <?xml version="1.0" encoding="UTF-8"?> <fileItem> <id>2</id> <name>X2</name> </fileItem> $ more fileItem_2.xml <?xml version="1.0" encoding="UTF-8"?> <fileItem> <id>2</id> <!--name>X2</name--> </fileItem> $
Tripleee的评论是合理的。因此,这种处理应限于个人使用,因为XML文件的不同(和合法)格式可能会导致此脚本处理中的错误。
您会注意到,next整个脚本中没有任何内容。这是故意的。
next