如何在没有填充磁盘空间的情况下在tar归档文件中的grep模式

我有一个很大的〜5GB的tar档案。

我想在所有文件上grep一个模式(也打印有模式的文件的名字),但是不想通过提取压缩文件来填满我的磁盘空间。

无论如何,我可以做到这一点?

我试过这些,但是这不会给我包含模式的文件名,只是匹配的行:

tar -O -xf test.tar.gz | grep 'this' tar -xf test.tar.gz --to-command='grep awesome' 

tar的这个特性还logging在哪里? tar xf test.tar $ FILE

这是我的承担:

 while read filename; do tar -xOf file.tar "$filename" | grep 'pattern' | sed "s|^|$filename:|"; done < <(tar -tf file.tar | grep -v '/$') 

解释为:

  • while read filename; do while read filename; do – 这是一个循环…
  • tar -xOf file.tar "$filename" – 这提取每个文件…
  • | grep 'pattern' | grep 'pattern' – 这里是你把你的模式…
  • | sed "s|^|$filename:|"; – 预先指定文件名,这看起来像grep。 盐味道。
  • done < <(tar -tf file.tar | grep -v '/$') – 结束循环,获取文件列表,以便while read

一个限制条件:如果文件名中包含或(*),则会中断。

嗯。 事实上,这使得一个很好的小bash函数,你可以附加到你的.bashrc文件:

 targrep() { local taropt="" if [[ ! -f "$2" ]]; then echo "Usage: targrep pattern file ..." fi while [[ -n "$2" ]]; do if [[ ! -f "$2" ]]; then echo "targrep: $2: No such file" >&2 fi case "$2" in *.tar.gz) taropt="-z" ;; *) taropt="" ;; esac while read filename; do tar $taropt -xOf "$2" \ | grep "$1" \ | sed "s|^|$filename:|"; done < <(tar $taropt -tf $2 | grep -v '/$') shift done } 

似乎没有人发布这个只处理一次存档的简单解决方案

 tar xzf archive.tgz --to-command \ 'grep --label="$TAR_FILENAME" -H PATTERN ; true' 

这里, tar传递变量中每个文件的名称(参见文档 ), grep使用它来打印每个匹配的文件。 也是true ,以便tar不会抱怨无法提取不匹配的文件。

这是一个bash函数,可能适合你。 将以下内容添加到~/.bashrc

 targrep () { for i in $(tar -tzf "$1"); do results=$(tar -Oxzf "$1" "$i" | grep --label="$i" -H "$2") echo "$results" done } 

用法:

 targrep archive.tar.gz "pattern" 

这是令人难以置信的哈​​克,但你可以滥用tar的-v选项来处理和删除每个文件,因为它被提取。

 grep_and_delete() { if [ -n "$1" -a -f "$1" ]; then grep -H 'this' -- "$1" </dev/null rm -f -- "$1" </dev/null fi } mkdir tmp; cd tmp tar -xvzf test.tar.gz | ( prev='' while read pathname; do grep_and_delete "$prev" prev="$pathname" done grep_and_delete "$prev" ) 
 tar -tf test.tar.gz | grep -v '/$'| \ xargs -n 1 -I _ \ sh -c 'tar -xOf test.tar.gz _|grep -q <YOUR SEARCH PATTERN> && echo _' 

尝试:

  tar tvf name_of_file |grep --regex="pattern" 

t选项将测试tar文件而不提取文件。 v是详细的,f打印他的文件名。 这应该为您节省相当大的硬盘空间。

可能有帮助

 zcat log.tar.gz | grep -a -i "string" zgrep -i "string" log.tar.gz 

http://www.commandlinefu.com/commands/view/9261/grep-compressed-log-files-without-extracting