Answers:
如果要递归grep当前目录中的所有.eml.gz文件,则可以使用:
find . -name \*.eml.gz -print0 | xargs -0 zgrep "STRING"
您必须转义第一个,*
以便外壳程序不解释它。-print0
告诉find在找到的每个文件之后打印一个空字符;xargs -0
从标准输入读取并在每个文件之后运行命令;zgrep
的工作方式类似于grep
,但先解压缩文件。
zgrep
实际上似乎比grep
在未压缩文件上运行快。一定是因为压缩文件可以从HD读取并且解压缩的速度比从HD读取未压缩的文件要快。
xargs
使用空格(空格)。当然,文件中几乎永远不会包含换行符,但是空格并不是闻所未闻的(即使大多数UNIXy类型都不喜欢它们)。就是说,您可以简化而不必更加担心空格:find . -name '*.eml.gz' -exec zgrep "STRING" {} +
每次启动时都会得到许多相同的参数xargs
,-print0
/ 的安全性-0
,并且所有操作都不会产生额外的过程启动和管道操作,而且非常简洁。-exec
用+
POSIX指定的,所以据我所知,它应该在大多数最近的类似UNIX的系统上。
ABCLog04_18_18_2_21.gz
有没有一种方法可以递归查找以ABC *开头的文件。我尝试\*.eml.gz
在上面的示例中替换为,ABCLog*
并收到有关文件格式的错误。:find: paths must precede expression: ABCLog-2018-03-12-10-16-1.log.gz Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
这里有很多混乱,因为不只是一个zgrep
。我有我的系统上两个版本,zgrep
从gzip
和zgrep
从zutils
。前者只是一个调用的包装器脚本gzip -cdfq
。它不支持该-r, --recursive
开关。1
后者是一个c++
程序,它支持该-r, --recursive
选项。
运行zgrep --version | head -n 1
将显示其中的哪一个(如果有)是默认值:
zgrep (gzip) 1.6
是包装脚本,
zgrep (zutils) 1.3
是cpp
可执行文件。
如果有后者,则可以运行:
zgrep 'pattern' -r --format=gz /path/to/dir
无论如何,如建议的那样,find
+ zgrep
可以在以下两个版本中同样有效zgrep
:
find /path/to/dir -name '*.gz' -exec zgrep -- 'pattern' {} +
如果zgrep
系统中缺少此文件(极不可能),可以尝试:
find /path/to/dir -name '*.gz' -exec sh -c 'gzip -cd "$0" | grep -- "pattern"' {} \;
但有一个主要缺点:您将不知道匹配项在哪里,因为在匹配行之前没有文件名。
1:因为这有问题
zgrep
无法使用zutils,则可以使用来在Ubuntu中安装它sudo apt-get install zutils
。
grep -n
,zgrep -n
将打印行号。在手册中...
ag
是的变体 grep
,具有一些不错的额外功能。
所以:
ag -r -z your-pattern-goes-here folder
如果未安装,
apt-get install silversearcher-ag (debian and friends)
yum install the_silver_searcher (fedora)
brew install the_silver_searcher (mac)
ag: truncated file: Success
结果我得到了。我还应该添加其他标志吗?
单独进行递归很容易:
-r, --recursive
Read all files under each directory, recursively, following
symbolic links only if they are on the command line. This is
equivalent to the -d recurse option.
-R, --dereference-recursive
Read all files under each directory, recursively. Follow all
symbolic links, unlike -r.
但是,对于压缩文件,您需要以下内容:
shopt globstar
for file in /path/to/directory/**/*gz; do zcat ""$file" | grep pattern; done
path/to/directory
应该是包含每天子目录的父目录。
zgrep
是明显的答案,但不幸的是,它不支持该-r
标志。来自man zgrep
:
这些grep选项将导致zgrep终止,并显示错误代码:(-[d rR zZ] | --di * | --exc * | --inc * | --rec * | --nu *)。
如果您的系统具有zgrep,则只需
zgrep -irs your-pattern-goes-here the-folder-to-search-goes-here/
如果您的系统没有zgrep,则可以使用find命令对每个文件运行zcat和grep,如下所示:
find the-folder-to-search-goes-here/ -name '*.gz' \
-exec sh -c 'echo "Searching {}" ; zcat "{}" | grep your-pattern-goes-here ' \;
Searching ~/gmvault-db/db/2015-02/03/whatever.gz
zgrep
-r
出于某种原因不会采取行动。在man zgrep
(也请参阅我的答案)中提到。
xzgrep -l“字符串” ./*/*.eml.gz
xzgrep是zgrep实用程序的衍生版本(减去/ bin / xzgrep)
在手册页中:
xzgrep对可能未压缩或使用xz(1),lzma(1),gzip(1),bzip2(1)或lzop(1)压缩的文件调用grep(1)。指定的所有选项都直接传递到grep(1)。
-l打印匹配的文件名
-R递归将不起作用,因为脚本中明确禁止它,但是简单的shell遍历应该可以使我们到达
./*/*.eml.gz
从./today/sample.eml.gz的相对路径匹配,在该实例的所有实例上都比我们在外壳中的相对位置低一级,并且以“ .eml.gz”结尾
zgrep
:zgrep - search possibly compressed files for a regular expression