如何在压缩文件中搜索文本并仅获取文件名

如何在压缩文件中搜索文本并仅获取文件名

我试图仅查找包含特定字符串的文件名。文件被压缩( .gz)。

我没有zgrep安装,也无法安装。因此我无法使用该-l选项。

我尝试过使用gzipandgunzip选项-c和 pipping togrep -l但这不起作用,我也使用过,zcat但这也不起作用。有什么线索吗?

(注:操作系统为Solaris 10)。

答案1

您可以手动完成 zgrep 的工作。由于您只需要文件名,因此grep仅用于测试模式是否存在,如果找到模式则打印出文件名。

#!/bin/sh
pattern=$1; shift
PATH=`getconf PATH`:$PATH # needed on Solaris 10 and earlier
                          # to get a standard grep
export PATH
found=0
for x do
  if case "$x" in
      *.gz|*.[zZ]) <"$x" gzip -dc | grep -q -e "$pattern";;
      *) <"$x" grep -q -e "$pattern";; 
     esac
  then
    found=1
    printf '%s\n' "$x"
  fi
done
if [ $found -eq 0 ]; then exit 1; fi

运行方式为:

that-script 'pattern' file1 file2.gz file3.Z file.*.gz ...

针对运行 Solaris 10 的一些具体说明(也适用于早期版本,在某些方面也适用于 Solaris 11)。

  • 在这些系统上,/bin/sh是 Bourne shell,而不是标准 POSIX sh。您可以选择更改您的 she-bang 以#! /usr/xpg4/bin/sh -获取标准sh,或者将自己限制为古老的 Bourne 语法,就像我们在这里所做的那样(所以不$(...),不case $x in (x)...)(Solaris 11 现在使用 POSIX 兼容的 shell 来实现它的/bin/sh( ksh93))。
  • 在这些系统上,zcat仅处理像以前那样.Z压缩的文件。compress您需要调用gzip文件.gz
  • 默认情况下,您不一定获得标准实用程序。例如,默认值是一个古老的grep选项/usr/bin,不支持标准-q选项。要获取标准实用程序,您需要更新$PATH查找标准实用程序的路径(如 的输出getconf PATH)。

如果要显示存档成员名称和行号或内容,则需要从 grep 获取行数据并从脚本获取成员名称。从调用中删除该-q选项grep,并对其内容进行后处理。

#!/bin/ksh
pattern=$1; shift
export PATH="$(getconf PATH):$PATH" # needed on Solaris 10 and earlier
                                    # to get a standard grep
found=0
for x do
  case "$x" in
      *.gz|*.[zZ]) <"$x" gzip -dc | grep -n -e "$pattern";;
      *) <"$x" grep -n -e "$pattern";; 
  esac | {
    filename=$x awk '{print ENVIRON["filename"] ":" $0; found=1}
                     END {exit(!found)}' && found=1
  }
done
if [ $found -eq 0 ]; then exit 1; fi

答案2

由于您的文件实际上是 tar.gz 文件,因此您还需要解压它们。 Tar 是一种归档实用程序,它将多个文件打包在一起(在您的情况下只有一个),最初用于将数据备份到磁带驱动器。

tar 实用程序最初并不压缩内容,因此通常通过 gzip 或其他实用程序进行流式传输以进行压缩。如果您解压缩 tar.gz,您仍然保留 tar 实现层,这就是它无法工作的原因。

如今,gun tar 将使用“z”命令通过一个命令为您进行 tar 和 zip 压缩。

因此,为了让您做您想做的事情,我认为您需要使用 tar 从文件目标“f”中提取“x”解压缩“z”并流到标准输出“O”,然后通过管道传输到 grep。它应该看起来像这样:

 tar -xzf mycompressedlogfile.tar.gz -O | grep -l "pattern"

由于您的 tar 版本没有 -z ,因此请尝试在 grep 之前通过 tar 管道传输 gzip 的输出

 gzip -dc mycompressedlogfile.tar.gz | tar -xOf - | grep -l "pattern"

但我不认为 Solaris 10 版本的 tar 支持“O”选项将 tar 内容流式传输到 stdout。 :( 您可能必须对工作目录中的每个文件执行上述操作(没有 O 所以“tar -xf -”),或者以某种方式确保您可以解释创建的文件,搜索抱歉,除非您可以在 Solaris 计算机上安装 gnu-tar。

我想从所选的答案中,您可以在 tar 流中搜索该模式(因为它没有被压缩,我想这是有道理的)并从那里找出答案..:) 很好。

很高兴你得到了答案。

答案3

这是另一个解决方案:

#!/bin/bash
# Grab the pattern, just like grep
re="$1"; shift

# Loop across the remaining arguments, or stdin if none
test 0 -eq $# && set -- -
for file
do
    # Search through the file (compressed or otherwise)
    zcat -f "$file" | grep -q "$re" && echo "$file"
done

您应该将其复制到一个文件中并使该文件可执行(chmod a+x {filename},然后使用它类似于zgrep

mkdir -p ~/bin
export PATH="$HOME/bin:$PATH"  # Add the ~/bin directory to your PATH. Also add this line to your ~/.profile

cat > ~/bin/mygrep             # Paste the file at this point, hit Ctrl/D on a blank line to end. Or otherwise edit ~/bin/mygrep
chmod a+x ~/bin/mygrep         # Make it executable

mygrep 'hello.*world' a*       # Search for the RE 'hello.*world' in all files beginning with 'a'

如果您发现zcat -fgrep -q未被识别,您可以将每个替换为以下内容

( zcat "$file" 2>/dev/null || cat "$file" )    # zcat -f "$file"
grep "$re" 2>/dev/null                         # grep -q "$re"

应用两种替换后,生成的替换行将如下所示

( zcat "$file" 2>/dev/null || cat "$file" ) | grep "$re" 2>/dev/null && echo "$file"

相关内容