查找一行中的多个字符串

查找一行中的多个字符串

我是 Unix 的新手,正在使用 CygWIN64 模拟器。我有大量的文本文件(数以万计),我需要搜索特定的字符串。我已经成功地自学使用单个字符串进行搜索,但经过几天的尝试后我无法弄清楚如何搜索两个字符串。

我的文件驻留在c:/BF/data/

我的单字符串命令是

grep -Rinw c:/BF/data/ -e 'string'

我已经尝试了很多在线示例,但无法获得任何命令来处理两个字符串(AND 结构,而不是 OR 结构)。如果这两个字符串出现在一行中,我希望该行显示在屏幕上。再一次,我已经能够用一根绳子做到这一点。该字符串中可能有一个空格 - 如果这有什么区别的话。例如,一个字符串可能是“迈阿密”,另一个字符串可能是“纽约市”。

我尝试过不同的grep命令,awk但没有任何效果。

有人可以指出我正确的方向吗?

答案1

要查找一行中的 2 个字符串:

将 GNU grep 与 Perl 兼容的正则表达式结合使用:

grep -RinP '^(?=.*\bMiami\b)(?=.*\bNew York City\b)' dir/

Perl 正则表达式用作\b单词边界。

使用 GNU awk:

gawk -v IGNORECASE=1 '
    /\<Miami\>/ && /\<New York City\>/ {
        print FILENAME ":" NR ":" $0
    }
' file

扩展正则表达式使用\<\>作为单词边界。

然而 awk 没有相当于-R.您可以使用查找:

find dir/ -type f -exec gawk -v IGNORECASE=1 '...' '{}' +

答案2

以下解决方案可在 @steeldriver 链接的帖子中找到,由 @Campa 提供。

grep -Rinw Miami . | grep -iw "new york city"

只需添加一些开关即可获得递归搜索和输出

使用

Miami banana
Miami New York City
Miami banana
New York City banana
Miami banana
New York City Miami

如果您有大量文件,那么避免使用Perlgrep似乎是个好主意

time grep -Rinw Miami . | grep -iw "new york city"
./file:2:Miami New York City
./file:6:New York City Miami

real    0m0.014s
user    0m0.004s
sys     0m0.016s

time grep -RinwP Miami . | grep -iwP "new york city"
./file:2:Miami New York City
./file:6:New York City Miami

real    0m0.059s
user    0m0.060s
sys     0m0.004s

与 @glennjackman 和erltime相比,上述内容似乎有一个优势P

time grep -RinP '^(?=.*\bMiami\b)(?=.*\bNew York City\b)' .
./file:2:Miami New York City
./file:6:New York City Miami

real    0m0.069s
user    0m0.062s
sys     0m0.007s

在同一个搜索中循环 1,000 次for i in {1..1000}; do ....; done似乎证实了这一点

@格伦杰克曼Perlgrep

real    0m49.276s
user    0m47.414s
sys     0m1.790s

@P坎帕埃尔grep

real    0m42.841s
user    0m42.305s
sys     0m3.346s

@坎帕简单grep

real    0m8.813s
user    0m8.837s
sys     0m3.081s

但 1,000 次重复冲刺中毫无疑问的获胜者是 @glennjackmanawk

real    0m2.975s
user    0m2.259s
sys     0m0.772s

相关内容