2011-11-25 64 views
0

我有一個大的日誌文件,超過100萬行。 我需要使用正則表達式來查找模式,然後開始咀嚼,直到我再次擊中另一個正則表達式。所以我最終會得到1500行。chomping file down

我知道sed允許使用regexp,但它可以拆分文件嗎?我沒有awk的經驗,但我認爲這應該讓我做我需要的。我很困惑從閱讀manpage,雖然...我會appriciate一些例子,甚至更簡單的解決方案。

+1

你能提供一些示例日誌文件的線條和正則表達式,你希望匹配?當有一些具體的輸入和輸出要討論時,制定解決方案總是更容易。 – Trott

回答

5

在這兩個AWK ANS SED你可以定義這樣的正則表達式 -

AWK:在AWK你會發現,我們沒有寫任何地方print。在AWK(這是基於模式/動作報表,打印是默認的動作,當圖案說法是正確的。因此,在下列情況下,每當正則表達式模式是真實的,AWK將打印對我們來說。

awk '/regex1/,/regex2/' INPUT_FILE > NEW_FILE 

SED:在SED我們使用-n選項來禁止打印一切的默認行爲,並使用正則表達式與p告訴SED打印特定線路

sed -n '/regex1/,/regex2/p' INPUT_FILE > NEW_FILE 

或者,你也可以給下面的一個-liner

sed '/regex1/,/regex2/!d' INPUT_FILE > NEW_FILE 

使用重定向操作符>您可以創建文件的子集。

對於AWK分割的文件,如果你知道記錄的數量,您的文件(wc -l < INPUT_FILE),那麼你可以寫這樣的事情 -

awk 'NR==2,NR==5' INPUT_FILE 

NR是AWK的內置變量被設置到記錄的行號。所以,如果你有1500行的文件,並只需要頂部750,那麼你可以做這樣的事情 -

awk 'NR==1,NR==750' INPUT_FILE 

正如前面提到的,你可以,但你沒有提到print與AWK。只要你的模式是真的,它會爲你做。

雖然在你的文件中有一百萬行,但這將是一大痛苦。所以下面的AWK單線程應該能夠做到這一點。

awk '{print >("SMALL_BATCH_OF_FILES_" int((NR+2)/3))}' BIG_INPUT_FILE 

此一襯墊將創建一個包含各3條線SMALL_BATCH_OF_FILES_。您可以將其設置爲您的舒適等級。(NR + 2/3)

執行:

[jaypal~/Temp]$ cat BIG_INPUT_FILE 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

[jaypal~/Temp]$ awk '{print >("SMALL_BATCH_OF_FILES_" int((NR+2)/3))}' BIG_INPUT_FILE 

[jaypal~/Temp]$ ls -lrt SMALL* 
-rw-r--r-- 1 jaypalsingh staff 3 25 Nov 10:41 SMALL_BATCH_OF_FILES_4 
-rw-r--r-- 1 jaypalsingh staff 6 25 Nov 10:41 SMALL_BATCH_OF_FILES_3 
-rw-r--r-- 1 jaypalsingh staff 6 25 Nov 10:41 SMALL_BATCH_OF_FILES_2 
-rw-r--r-- 1 jaypalsingh staff 6 25 Nov 10:41 SMALL_BATCH_OF_FILES_1 

[jaypal~/Temp]$ cat SMALL_BATCH_OF_FILES_1 
1 
2 
3 
[jaypal~/Temp]$ cat SMALL_BATCH_OF_FILES_2 
4 
5 
6 
[jaypal~/Temp]$ cat SMALL_BATCH_OF_FILES_3 
7 
8 
9 
[jaypal~/Temp]$ cat SMALL_BATCH_OF_FILES_4 
10 
+0

謝謝你的這個徹底的答案與很多的例子。乾杯! – WraithLux

1

perl -ne 'print if /start pattern/ .. /end pattern/'將打印任何有一個匹配/start pattern/開始,以一個匹配/end pattern/結束行的順序。如果您想在第一個這樣的區塊後退出,您可以使用perl -ne 'print if /start pattern/ .. 0; last if /end pattern/'

第一個也可以在awk中完成:/start pattern/, /end pattern/ { print }

第二個也可以在awk中完成,但我不知道那麼多awk。

0

只是,已經提出

awk '/regexp1/,/regexp2/' 

假定輸入文件中的溶液的一個例子是

0 zzz 
1 aaa 
2 bbb 
3 ccc 
4 aaa 
5 ddd 
6 ccc 
7 aaa 
8 ddd 
9 eee 
10 ddd 
11 zzz 

命令

awk '/a/, /d/' file.txt 

將提取兩個子集:行1到5(注意4 aaa被忽略)和線7〜8(注意:10 ddd被忽略)

1 aaa 
2 bbb 
3 ccc 
4 aaa 
5 ddd 
7 aaa 
8 ddd