2010-11-11 56 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