2010-11-11 54 views
3

我想從壓縮的.gz文件中的文件中獲取幾行。在壓縮的.gz文件中搜索的Unix腳本

.gz文件包含很多txt文件,我想在所有這些txt文件中搜索一個字符串,並且需要獲取前面的3行作爲輸出,包括當前行(搜索字符串所在的行)。

我試過zgrep並得到了行號,但是當我使用headtail時,它給出了一些垃圾值。我認爲我們不能使用包含多個文件的壓縮文件的headtail命令。

請建議是否有簡單的方法?

+0

是否有可能重新這個,這樣就很清楚這是一個.tar.gz。你想只在一個文件中使用前三行嗎?或者如果它從前一個文件中報告一行? – wnoise 2010-11-12 00:06:50

+0

來自一個文件/同一文件的前三行 – CFUser 2010-11-12 00:18:44

+0

Zip文件!= tar-balls。請修復措辭。 – 2010-11-12 19:16:18

回答

5

如何做到這一點的本質是獲取壓縮包中文件的名稱進行搜索,並提取他們的內容進行搜索,而不是提取其他任何東西。因爲我們不想寫入文件系統,所以我們可以使用-O標誌來提取標準輸出。

tar -tzf file.tar.gz | grep '\.txt' | xargs tar -Oxzf file.tar.gz | grep -B 3 "string-or-regex"會將.tar.gz中的所有文件與名稱以「.txt」結尾,而grep連接到給定的字符串,並輸出前面3行。它不會告訴你tar包中的哪個文件來自任何匹配,並且「之前的三行」實際上可能來自前一個文件。

可以代替做:

for file in $(tar -tzf file.tar.gz | grep '\.txt'); do 
    tar -Oxzf file.tar.gz "$file" | grep -B 3 --label="$file" -H "string-or-regex" 
done 

將尊重文件邊界,並報告了文件名,但要有效得多。

-z告訴targzip壓縮。-t列表內容。-x提取物。-O重定向到標準輸出,而不是文件系統。舊tar S可沒有-O-z標誌,並希望標誌不-:例如tar tz file.tar.gz

好的,所以你有一個不可用的grep。我們可以用awk解決這個問題!

#!/usr/bin/awk -f 
BEGIN { context=3; } 
{ add_buffer($0) } 
/pattern/ { print_buffer() } 
function add_buffer(line) 
{ 
    buffer[NR % context]=line 
} 
function print_buffer() 
{ 
    for(i = max(1, NR-context+1); i <= NR; i++) { 
     print buffer[i % context] 
    } 
} 
function max(a,b) 
{ 
    if (a > b) { return a } else { return b } 
} 

這不會聚結相鄰的匹配,不像的grep -B,並且因此可以重複 是在3線的兩個不同的匹配線。

+0

我的操作系統不支持-B或-A命令 – CFUser 2010-11-12 00:33:07

+0

它支持-C?之後獲得3行是否也是一個問題? – wnoise 2010-11-12 00:43:50

+0

不幸的是沒有C:( – CFUser 2010-11-12 01:19:06

0

這可能是一個tar文件的gzip?最簡單的就是提取整個事物並在提取的文件上使用常規工具。

+2

是它的tar文件的gzip。我無法解壓,bcoz它包含巨大的文件,並會得到磁盤空間問題 – CFUser 2010-11-11 23:37:30