Linux Grep 在目录中的所有文件中搜索 string1 和 string2

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4275900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 00:07:23  来源:igfitidea点击:

Grep Search all files in directory for string1 AND string2

linuxshellgrep

提问by Abs

How can I make use of grep in cygwin to find all files that contain BOTHwords.

如何在 cygwin 中使用 grep 查找包含两个单词的所有文件。

This is what I use to search all files in a directory recursively for one word:

这是我用来递归搜索目录中所有文件的一个词:

grep -r "db-connect.php" .

How can I extend the above to look for files that contain both "db-connect.php" AND "version".

如何扩展上述内容以查找同时包含“db-connect.php”和“version”的文件。

I tried this: grep -r "db-connect.php\|version" .but this is an OR i.e. it gets file that contain one or the other.

我试过这个:grep -r "db-connect.php\|version" .但这是一个或,即它获取包含一个或另一个的文件。

Thanks all for any help

感谢大家的帮助

采纳答案by moinudin

grep -r db-connect.php . | grep version

回答by jzrk

grep "db-connect.php" * | cut -d: -f1 | xargs grep "version"

grep "db-connect.php" * | 剪切 -d: -f1 | xargs grep“版本”

I didn't try it in recursive mode but it should be the same.

我没有在递归模式下尝试过,但应该是一样的。

回答by glenn Hymanman

Do you mean "string1" and "string2" on the same line?

你的意思是“string1”和“string2”在同一行吗?

grep 'string1.*string2'

On the same line but in indeterminate order?

在同一条线上但顺序不确定?

grep '(string1.*string2)|(string2.*string1)'

Or both strings must appear in the file anywhere?

或者两个字符串都必须出现在文件中的任何地方?

grep -e string1 -e string2

回答by Paused until further notice.

The uses PCRE (Perl-Compatible Regular Expressions) with multiline matching and returns the filenames of files that contain both strings (ANDrather than OR).

使用具有多行匹配的 PCRE(Perl 兼容正则表达式)并返回包含两个字符串(AND而不是OR)的文件的文件名。

grep -Plr '(?m)db-connect\.php(.*\n)*version|version(.*\n)*db-connect\.php' .

回答by tchrist

To andtogether multiple searches, use multiple lookahead assertions, one per thing looked for apart from the last one:

要将and多个搜索放在一起,请使用多个先行断言,除了最后一个之外,每件事寻找一个:

instead of writing

而不是写作

grep -P A  * | grep B

you write

你写

grep -P '(?=.*A)B' *

grep -Pr '(?=.*db-connect\.php)version' .

Don't write

不要写

grep -P 'A.*B|B.*A' *

because that fails on overlaps, whereas the (?=…)(?=…)technique does not.

因为在重叠时会失败,而该(?=…)(?=…)技术则不会。

You can also add in NOToperators as well. To search for lines that don't match X, you normally of course use -von the command line. But you can't do that if it is part of a larger pattern. When it is, you add (?=(?!X).)*$)to the pattern to exclude anything with Xin it.

您也可以添加NOT运算符。要搜索不匹配的行X,您当然通常-v在命令行上使用。但是如果它是更大模式的一部分,你就不能这样做。当它是时,您添加(?=(?!X).)*$)到模式以排除其中的任何X内容。

So imagine you want to match lines with all three of A, B, and then either of C or D, butwhich don't have X or Y in them. All you need is this:

因此,假设您想将 A、B 和 C 或 D 中的所有三个匹配行,其中没有 X 或 Y。你只需要这个:

grep -P '(?=^.*A)(?=^.*B)(?=^(?:(?!X).)*$)(?=^(?:(?!Y).)*$)C|D' *

In some shells and in some settings. you'll have to escape the !if it's your history-substitution character.

在某些外壳和某些设置中。!如果它是您的历史替换字符,您将不得不逃避。

There, isn't that pretty cool?

那里,是不是很酷?

回答by incircuitous

In my cygwin the given answers didn't work, but the following did:

在我的 cygwin 中,给出的答案不起作用,但以下内容有效:

grep -l firststring `grep -r -l secondstring . `

回答by Coroos

If you want to grep for several strings in a file which have different lines, use the following command:

如果要对文件中具有不同行的多个字符串进行 grep,请使用以下命令:

grep -rl expr1 | xargs grep -l expr2 | xargs grep -l expr3

This will give you a list of files that contain expr1, expr2, and expr3.

这将为您提供包含 expr1、expr2 和 expr3 的文件列表。

Note that if any of the file names in the directory contains spaces, these files will produce errors. This can be fixed by adding -0 I think to grep and xargs.

请注意,如果目录中的任何文件名包含空格,这些文件将产生错误。这可以通过将 -0 添加到 grep 和 xargs 来解决。

回答by Vijay

Why to stick to only grep:

为什么坚持只使用grep:

perl -lne 'print if(/db-connect.php/&/version/)' *