【问题标题】:Searching two patterns in files that appear in the same file but may not appear on the same line搜索出现在同一文件中但可能不在同一行的文件中的两个模式
【发布时间】:2020-10-07 13:09:58
【问题描述】:

从一个目录中,我需要找到所有包含十进制数字的文件,例如 42.7 和关键字“foo”或“goo”。我怎样才能做到这一点?

假设我有一个包含三个文件的目录

file1.txt
=======
double x = 2.7
foo();

file2.txt
===========
double u = 5.7

file3.txt
===========
goo(42.0); 

搜索命令应该给出 file1.txt 和 file3.txt。实现此目的的搜索命令是什么?

我搜索了解决方案,但我能找到的只是让模式同时出现在同一行中。我也很难处理小数点。

【问题讨论】:

  • 我在任何地方都没有看到42.7,有什么文件与之匹配?
  • Re "decimal dot" -- 你试过转义它吗? (在 bash 和正则表达式中?——这应该已经在某个地方得到了回答)

标签: regex linux shell grep


【解决方案1】:

使用 2 个grep -l 命令列出包含正则表达式的文件名(不是匹配的行)。通过xargs 连接它们,例如:

grep -Pl '(\d+[.]?\d*|\d*[.]?\d+)' file?.txt | xargs grep -Pl '(foo|goo)'

例子:

创建输入文件。除了问题中列出的示例之外,我还使用了一些示例来说明找到的模式/文件:

cat > file1.txt <<EOF
double x = 2.7
foo();
EOF

cat > file2.txt <<EOF
double u = 5.7
EOF

cat > file3.txt <<EOF
goo(42.0);
EOF

cat > file4.txt <<EOF
foo(4);
EOF

cat > file5.txt <<EOF
goo(.42);
EOF

cat > file6.txt <<EOF
goo(.);
EOF

运行grep -l ... | xargs grep -l ... 查找匹配文件:

grep -Pl '(\d+[.]?\d*|\d*[.]?\d+)' file?.txt | xargs grep -Pl '(foo|goo)'

打印:

file1.txt
file3.txt
file4.txt
file5.txt

这里,grep 使用以下选项:
-P:使用 Perl 正则表达式。
-l:仅列出文件名,而不是匹配的行。

正则表达式包含以下部分:
\d*:0-9 的任意数字,重复 0 次或多次。
\d+:相同,重复 1 次或多次。
[.] : 文字点 (.)。否则,不转义,. 表示任何字符。

另请参阅:

-l
--files-with-matches

抑制正常输出;而是打印每个输入文件的名称 通常会打印哪个输出。每个人的扫描 文件在第一次匹配时停止。 (-l 由 POSIX 指定。)

grep manual

【讨论】:

  • 谢谢。为什么使用 Perl 正则表达式?是标准吗?
  • @zell Perl 正则表达式不是标准的,但它是 GNU grep 的一个选项。我喜欢它,因为它通常更容易编写和维护。但是如果你愿意,你可以使用标准的正则表达式重写它。
猜你喜欢
  • 1970-01-01
  • 2017-12-23
  • 1970-01-01
  • 2014-11-23
  • 1970-01-01
  • 2011-03-09
  • 2013-12-03
  • 1970-01-01
  • 2011-04-09
相关资源
最近更新 更多