我正在尝试将大型xml文件拆分为几个较小的文件。我找到了将每个节点拆分成自己文件的解决方案:
awk '/<mono/{close("row"count".xml");count++}count{f="row"count".xml";print $0 > f}' file.xml
上面的代码匹配每个“mono”节点并将其输出到文件名行{rownumber} .xml。如何将每20个匹配项打印到文件中?
答案 0 :(得分:1)
保持两个计数 - 当前计数和重复计数。当重复计数模20处于适当的值(在所示代码中为0和1)时,仅执行当前活动(打印标记):
awk '/<mono/ { if (repeat++ % 20 == 0) { close("row"count".xml"); count++ } }
count && repeat % 20 == 1 { f = "row"count".xml"; print $0 > f}' file.xml
第二个条件中的'== 1'条件有点凌乱;可能有更好的方法来处理这种逻辑。
请注意,您的代码也会将“<monotonous>
”视为Mono。
将文件1中的记录1-20,文件2中的21-40等分组......
同样的一般想法适用...你有一个文件号和一个匹配的记录号,你可以适当地处理它们。经过测试的代码:
awk '/<mono/ { if (recno > 1 && recno % 20 == 0) { close(file); count++;}
if (recno % 20 == 0) { file = "row" count ".xml" }
print $0 > file
recno++
}' file.xml
第一个文件是row.xml
。后续文件为row1.xml
等。
我在这样的文件上测试了这个:
<mono> <tonous val=001/> </mono>
ignore
<mono> <tonous val=002/> </mono>
<mono> <tonous val=003/> </mono>
<mono> <tonous val=004/> </mono>
<mono> <tonous val=005/> </mono>
ignore
<mono> <tonous val=006/> </mono>
<mono> <tonous val=007/> </mono>
<mono> <tonous val=008/> </mono>
<mono> <tonous val=009/> </mono>
ignore
<mono> <tonous val=010/> </mono>
<mono> <tonous val=011/> </mono>
<mono> <tonous val=012/> </mono>
<mono> <tonous val=013/> </mono>
<mono> <tonous val=014/> </mono>
ignore
<mono> <tonous val=015/> </mono>
<mono> <tonous val=016/> </mono>
<mono> <tonous val=017/> </mono>
<mono> <tonous val=018/> </mono>
<mono> <tonous val=019/> </mono>
ignore
<mono> <tonous val=020/> </mono>
<mono> <tonous val=021/> </mono>
<mono> <tonous val=022/> </mono>
<mono> <tonous val=023/> </mono>
ignore
<mono> <tonous val=024/> </mono>
...
它包含100条<mono>
行和一些ignore
行(有些重复)。它生成了文件row.xml
,row1.xml
,... row4.xml
,每行包含20行。这是在MacOS X 10.6.6上使用标准(BSD)awk
测试的。
答案 1 :(得分:1)
我会说保留“计数”变量,您只需要更改构建文件名的方式:f="row" int(count/20) ".xml"
您不必显式关闭该文件。当awk退出时,所有打开的文件都将被关闭。鉴于评论,我会发表评论。请注意,在下面的代码中,文件最多关闭20次,但会根据需要重新打开。
awk '
/<mono/ {close f; count++; f = "row" int(count/20) ".xml"}
count {print >> f}
' file.xml