我想从压缩.gz文件中的文件中获取几行.
.gz文件包含许多txt文件,我想在所有这些txt文件中搜索字符串,并且需要将前3行作为输出,包括当前行(搜索字符串存在的位置).
我尝试zgrep并获得了行号,但是当我使用head或tail命令它给出了一些垃圾值.我认为我们不能将heador tail命令用于包含多个文件的压缩文件.
请建议是否有简单的方法?
如何实现这一点的本质是获取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
Run Code Online (Sandbox Code Playgroud)
它将尊重文件边界,并报告文件名,但效率低得多.
(-z告诉tar它是gzip压缩的.-t列出内容. -x摘录. -O重定向到标准输出而不是文件系统.较旧的tars可能没有-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 }
}
Run Code Online (Sandbox Code Playgroud)
与grep -B不同,这不会合并相邻的匹配,因此可以重复两个不同匹配的3行内的行.