![如何在压缩文件中搜索文本并仅获取文件名](https://linux22.com/image/75618/%E5%A6%82%E4%BD%95%E5%9C%A8%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6%E4%B8%AD%E6%90%9C%E7%B4%A2%E6%96%87%E6%9C%AC%E5%B9%B6%E4%BB%85%E8%8E%B7%E5%8F%96%E6%96%87%E4%BB%B6%E5%90%8D.png)
我试图仅查找包含特定字符串的文件名。文件被压缩( .gz
)。
我没有zgrep
安装,也无法安装。因此我无法使用该-l
选项。
我尝试过使用gzip
andgunzip
选项-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,而不是标准 POSIXsh
。您可以选择更改您的 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 -f
或grep -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"