2014-05-07 36 views
1

我有一個基於awk的拆分器,它基於正則表達式分割大型文件。但問題是,我收到了太多的文件錯誤。即使我有條件關閉。如果你能幫我弄清楚我做錯了什麼,我會非常感激。awk錯誤「使得打開的文件太多」

awk 'BEGIN { system("mkdir -p splitted/sub"++j) } 
    /<doc/{x="F"++i".xml";}{ 
    if (i%5==0){ 
     ++i; 
     close("splitted/sub"j"/"x); 
     system("mkdir -p splitted/sub"++j"/"); 
     } 
    else{ 
     print > ("splitted/sub"j"/"x); 
    } 
    }' wiki_parsed.xml 
+0

廣東話你只是用'csplit'? –

+0

我嘗試使用csplit,但遞歸目錄創建不可能使用csplit知識。所以我選擇了awk。 – xecutioner

+0

在這種情況下不好使用awk。 awk命令中有完整的純shell命令。直接在shell腳本中寫入 – BMW

回答

4

簡單的答案是關閉不經常被調用。這就是爲什麼一個說明性的例子:

使用等的輸入文件:

<doc somestuff 
another line 
yet another line 
<doc the second 
still more data 
<doc the third 
<doc the fourth 
<doc the fifth 

我可以做一個可執行AWK文件,根據你的腳本,如:

#!/usr/bin/awk -f 

BEGIN { system_(++j) } 

/<doc/{x=++i} 

{ 
    if (i%5==0){ ++i; close_(j"/"x); system_(++j) } 
    else{ open_(j"/"x) } 
} 

function call_f(funcname, arg) { print funcname"("arg")" } 

function system_(cnt) { call_f("system", cnt) } 
function open_(f) { if(!(f in a)) { call_f("open", f); a[f]++ } } 
function close_(f) { call_f("close", f) } 

它,如果我投入名爲awko的文件可以像awko data一樣運行以生成以下內容:

system(1) 
open(1/1) 
open(1/2) 
open(1/3) 
open(1/4) 
close(1/5) 
system(2) 

我所做的腳本只是通過使用尾隨_的本地函數映射實際函數調用來指示您調用每個函數的次數。請注意,與close()相比,open()的打印次數相同。另外,我最終將print >重命名爲open_,只是爲了說明它是什麼打開文件(每個文件名一次)。

如果我更改可執行AWK文件到以下幾點,就可以看清近處的被稱爲足夠:

#!/usr/bin/awk -f 

BEGIN { system_(++j) } 

/<doc/{ close_(j"/"x); x=++i } # close_() call is moved to here. 

{ 
    if (i%5==0){ ++i; system_(++j) } 
    else{ open_(j"/"x) } 
} 

function call_f(funcname, arg) { print funcname"("arg")" } 

function system_(cnt) { call_f("system", cnt) } 
function open_(f) { if(!(f in a)) { call_f("open", f); a[f]++ } } 
function close_(f) { call_f("close", f) } 

這給下面的輸出:

system(1) 
close(1/) 
open(1/1) 
close(1/1) 
open(1/2) 
close(1/2) 
open(1/3) 
close(1/3) 
open(1/4) 
close(1/4) 
system(2) 

,它應該清楚的是close()被稱爲一次又一次。第一次被調用的文件不存在。在真正的close()調用中,這樣的文件從未打印過的事實應該被忽略,並且不會嘗試實際關閉。在其他情況下,最後的open()匹配close()呼叫。

在第二個示例腳本中移動腳本close()應該修復錯誤。

0

這就是我得到它是工作完美

awk 'BEGIN { system("mkdir -p splitted/sub"++j) } 
    /<doc/{x="F"++i".xml";}{ 

     if (i%1995==0){ 
     ++i; 
     system("mkdir -p splitted/sub"++j"/"); 
     } 
     else{ 
     print >> ("splitted/sub"j"/"x); 
     close("splitted/sub"j"/"x); 
     } 

    }' wiki_parsed.xml 
相關問題