2011-03-07 114 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

相關問題