2011-03-07 111 views
0

我想将一个大的xml文件拆分为几个较小的文件。我发现了一个解决方案,每个节点分割到它自己的文件:如何使用awk打印每第n个匹配

上面的代码每个“单声道”节点,并输出到一个文件名行{} ROWNUMBER .XML匹配。我怎样才能每20个匹配打印一个文件?

回答

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 
+0

从'gawk'' info'文件中:“这是关闭输出文件的一些原因:...要在同一'awk'程序中连续写入大量文件如果文件没有关闭,最终'awk'可能超过系统对一个进程中打开文件数量的限制,最好在程序写完后关闭每一个文件。“ – 2011-03-07 16:02:09

+0

如果有30,000,000条记录,则需要关闭每个文件。 – 2011-03-07 16:24:25

+0

这很简单,并达到我所需要的。虽然我不知道发生了什么事。 – spyderman4g63 2011-03-07 17:14:26

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-20文件1,21-40 file2中,等...

同样的总体思路适用......你有一个文件编号和匹配的记录数量,以及你适当地处理它们。测试代码:

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进行了测试。

+0

我认为这是正确的方向,但由于我打印到“行”计数“.xml”我仍然得到每个节点单独的文件。我试图打印到“行”重复“.xml”,我得到每20行1个文件,但是我只在每个文件中获得1个节点。 – spyderman4g63 2011-03-07 14:08:27

+0

我想我错了。我想将第1-20行,第21-40行等打印到单独的文件中。 – spyderman4g63 2011-03-07 14:43:15

+0

@ spyderman4g63:在另外两个之后将'print'移到它自己的'{}'块中。 – 2011-03-07 16:08:50

相关问题