2017-01-26 54 views
1

我需要根據大文件中使用shell腳本最後一次出現的模式將較大的文件拆分成更小的塊。例如。在shell腳本中將大文件拆分成小塊在

Sample.txt的

NORTH EAST|0004|00001|Fost|Weaather|<br/> 
NORTH EAST|0004|00001|Fost|Weaather|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 
EAST|0007|00016|uytr|kert|<br/> 
EAST|0007|00016|uytr|kert|<br/> 
WEST|0002|00112|WERT|fersg|<br/> 
WEST|0002|00112|WERT|fersg|<br/> 
SOUTHWEST|3456|01134|GDFSG|EWRER|<br/> 

「模式1 = 00003」將要搜索的輸出文件必須包含sample_00003.txt(文件將基於要在其上被搜索圖案的第三字段排序)

NORTH EAST|0004|00001|Fost|Weaather|<br/> 
NORTH EAST|0004|00001|Fost|Weaather|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 
SOUTH|0003|00003|Haet|Summer|<br/> 

「Pattren 2 = 00112」 將要搜索的輸出文件必須包含sample_00112.txt

EAST|0007|00016|uytr|kert|<br/> 
EAST|0007|00016|uytr|kert|<br/> 
WEST|0002|00112|WERT|fersg|<br/> 
WEST|0002|00112|WERT|fersg|<br/> 

使用

awk -F'|' -v 'pattern="00003"' '$3~pattern big_file' > smallfile 

和grep命令,但它是非常耗時,因爲文件是300 + MB的大小。

+0

你所說的「最後一次出現的意思是的模式「? – codeforester

+0

模式在文件中匹配的最後時間。 I.e模式「00003」在第三個字段中匹配sample.txt文件的第5行。所以進程想把它分割出來,直到第5行成爲一個單獨的文件。 – Katchy

+1

將來,請使用突出顯示的文本編輯框左上方的格式化工具將其格式化爲代碼/數據/輸出。 祝你好運。 – shellter

回答

2

不知道你是否會比awk找到一個更快的工具,但在這裏,修復自己的嘗試,也是一個變種利用字符串匹配而不是正則表達式匹配速度的東西了一點。

它處理在一個循環中查找值,並且輸出一切從先前迭代通過最後發生值的離開的地方在手到名爲smallfile<n>文件,其中<n>是開始1的索引。

ndx=0; fromRow=1 
for val in '00003' '00112' '|'; do # 2 sample values to match, plus dummy value 
    chunkFile="smallfile$((++ndx))" 
    fromRow=$(awk -F'|' -v fromRow="$fromRow" -v outFile="$chunkFile" -v val="$val" ' 
    NR < fromRow { next } 
    { if ($3 != val) { if (p) { print NR; exit } } else { p=1 } } { print > outFile } 
    ' big_file) 
done 

需要注意的是虛值|確保最後一個真正的價值相匹配後的任何剩餘行保存到塊文件了。


注意,移動所有的邏輯放到一個awk腳本要快很多,因爲big_file將只需要讀取一次

awk -F'|' -v vals='00003|00112' ' 
    BEGIN { split(vals, val); outFile="smallfile" ++ndx } 
    { 
    if ($3 != val[ndx]) { 
     if (p) { p=0; close(outFile); outFile="smallfile" ++ndx } 
    } else { 
     p=1 
    } 
    print > outFile 
    } 
' big_file 
0

你可以用Perl嘗試:

perl -ne '/00003/ && print' big_file > small_file 

,並與其他解決方案,比較其定時...

編輯

限制我的回答對你沒有嘗試已的工具...你也可以使用:

sed -n '/00003/p' big_file > small_file 

但我傾向於認爲perl會更快。再次...我建議你自己衡量不同解決方案的使用時間。

+0

@ mklement0:我想你在評論之前測試了這些「有缺陷的嘗試」的性能...... – mauro

+0

我想你誤解了,所以讓我嘗試以不同的方式解釋它:OP描述了一個問題,並在解決方案中包含了_attempt_ 'awk'命令)。 這種嘗試在技術上有缺陷,但更重要的是,它在概念上有點基本上存在缺陷 - 即使是固定的,這種嘗試也不能解決問題。 您的答案中包含_technically_正確的命令,它與概念上有缺陷的嘗試相同,因此不解決OP的問題。 – mklement0

相關問題