用于在压缩的.gz文件中搜索的Unix脚本

时间:2010-11-11 23:30:47

标签: unix shell grep

我想从压缩的.gz文件中的文件中获取几行。

.gz文件包含许多txt文件,我想在所有这些txt文件中搜索字符串,并且需要将前3行作为输出,包括当前行(搜索字符串所在的位置)。

我尝试了zgrep并获得了行号,但是当我使用headtail命令时它会给出一些垃圾值。我认为我们不能将headtail命令用于包含多个文件的压缩文件。

请建议是否有简单的方法?

2 个答案:

答案 0 :(得分:5)

如何实现这一目标的本质是获取tarball中的文件名称进行搜索,并提取要搜索的内容,而不提取任何其他内容。因为我们不想写入文件系统,所以我们可以使用-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行。它不会告诉你任何匹配来自tarball中的哪个文件,并且“前三行”实际上可能来自上一个文件。

您可以改为:

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告诉tar压缩gzip-t列出内容。-x提取。-O重定向到标准输出比较文件系统。较早的tar可能没有-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行。

答案 1 :(得分:0)

这可能是tar文件的一个gzip吗?最简单的只是提取整个事物并在提取的文件上使用常规工具。