我是 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
如果您有大量文件,那么避免使用P
erlgrep
似乎是个好主意
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
似乎证实了这一点
@格伦杰克曼P
erlgrep
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