我同时从多个日志中抓取内容grep -Er
但我只想匹配一次文件前缀。
我想要实现的目标有点像ls -lr
(匹配文件一次,然后是每个所述文件的所有匹配行)
我在手册上没有找到这个选项。
我可以只用 grep 来实现它吗?如何 ?
答案1
grep
据我所知,没有任何实现。-r
本身并不是一个标准选项。您可以轻松地在脚本或函数中实现一个用于find
查找文件并perl
进行匹配和报告文件路径的函数。
rPgrep() {
local pattern="$1"
shift
find -- "$@" -type f -print0 |
perl -C -0se '
@ARGV = <STDIN>;
$ /= "\n";
while (<<>>) {
if (/$pattern/) {
unless ($header_already_printed) {
print "\n" if defined $header_already_printed;
print "$ARGV:\n";
$header_already_printed = 1;
}
print;
}
$header_already_printed &&= 0 if eof;
}' -- -pattern="$pattern"
}
进而:
rPgrep pattern some/dir some/other/dir or/regular/file
如果您还想查看常规文件的符号链接,请替换-type
为-xtype
(假设为 GNU )。find
或者添加-L
选项,以便在像 GNU (而不是)find
那样沿目录树下降时也遵循符号链接。grep -R
-r
作为奖励,您可以获得 perl 正则表达式(类似于一些grep
支持的-P
),而不是有限的延长那些你得到的-E
。
不区分大小写的匹配 ( -i
) 或单词匹配 ( -w
) 或反向匹配 ( -v
) 或整行匹配 ( -x
) 可以使用正则表达式语法 ( (?i)
, \b
, (?!...)
, ^...\z
) 来完成,但对于其他grep
选项 ( -n
, -l
,-F
或一些非标准扩展,如-o
// -A
/ -B
) -C
..., perl 代码必须修改。
您还可以执行以下操作:
find . -type f -exec grep -q pattern {} ';' \
-exec printf '\n%s:\n' {} ';' \
-exec grep pattern {} ';'
但这意味着每个文件最多运行三个命令,因此效率非常低。
对于 GNU find
,-exec printf '\n%s:\n' {} ';'
可以替换为-printf '\n%p:\n'
.