我想查找包含两个字符串的文件,例如文件同时包含string1
和string2
。
我想要输出文件的完整路径。我不想看到“权限被拒绝”警告。
答案1
grep -l string2 `grep -l string1 /path/*`
这与
grep -l string2 $(grep -l string1 /path/*)
编辑:这就是为什么它grep string1 /path/* | grep string2
没有按照我认为 alwbtc 想要的方式运行。
$ cd /tmp
$ cat a
apples
oranges
bananas
$ cat b
apples
mangoes
lemons
$ cat c
mangoes
limes
pears
$ cd ~
$ grep apples /tmp/* | grep mangoes
$
未找到任何内容,但文件 b 包含这两个字符串。
我认为 alwbtc 想要的是
$ grep -l apples $(grep -l mangoes /tmp/*)
/tmp/b
答案2
我正在寻找一种可扩展的方式来做 2或者更多字符串并得出了这个:
grep -rl string1 path-to-files | xargs grep -l string2 | xargs grep -l string3
string1
第一个 grep 递归地查找包含的文件的名称path-to-files
。
结果通过管道传输到xargs
其中,在这些文件上运行一个或多个 grep 命令string2
。
然后将结果传送到另一个xargs
命令中string3
- 它与第一个调用相同xargs
,但寻找不同的字符串。
使用xargs
将避免因结果太多而导致使用反引号导致的命令行太长的问题。
为了避免警告,我们可以重定向stderr
到/dev/null
:
grep -rl string1 path-to-files 2>/dev/null | xargs grep -l string2
在后续的 grep 调用中不需要它,因为string1
已经在文件内部找到了它,所以知道权限是好的。
答案3
以下是等价的确认命令RedGrittyBrick 的回答:
ack string2 $(ack string1 -l)
工作方式相同(除了默认情况下递归搜索当前目录)。搜索ack
的内容仅输出找到该字符串的文件名。然后将它们作为参数传递到外部命令,这意味着仅在这些文件列表中进行搜索。$()
string1
-l
string2
答案4
将一个管道连接grep
到另一个管道:
grep "string1" /path/to/files/* | grep "string2"