查找所有不同的正则表达式结果,而不是全部在一行中

Find all distinct regex results, not all in one line

我想在我的项目中找到传递给 __() 函数的所有不同参数。到目前为止,我构建的最好的 grep 调用是这个:

find . -name "*.php" | xargs grep "__('.*')" -sioh

它成功地找到了所有对__()函数的调用,但是它有以下问题:

  1. 它打印整个 __() 函数调用,而不仅仅是参数
  2. 当在原始文件的同一行中多次调用函数时,它会在同一行中打印两个函数调用

我想要的是传递给函数的所有不同参数的列表,所以我希望每个参数都在自己的行中(开头没有 __(,后面没有 )结束)。

对于如下所示的示例行:

/* Some code */ __('foo'); /* Some more code */ __('bar'); /* Even more code */

我的命令returns结果如下:

__('foo'); /* Some more code */ __('bar')

我想得到的是这个(在没有引号的不同行中):

foo
bar

已编辑:

事实证明,第一个参数并不总是单引号字符串。有时它是一个变量(以 $ 符号开头,因为它是 PHP,并且可以选择具有数组索引,例如 $a['b'])。

还有两个可选的布尔参数。但这只是我真正关心的结果中的第一个参数,其他两个并不重要。

使用这个 grep -P (PCRE):

grep -HoP '__\(\K[^)]*' *.php
file.php:'foo'
file.php:'bar'

找到__\(\K重置匹配数据。 [^)]* 然后查找 ).

之前的文本

这不如 anubhava 的答案好,但它更好,适用于没有 PCRE 标志的 grep。

在匹配中使用 [^)]* 而不是 .* 将在函数末尾停止匹配,而不是在行中最后一个函数调用的末尾。

$ grep -sioh "__('[^)]*')" *.php
__('foo')
__('bar')

这个答案假设如下,与 OP 后来的澄清一致:
- __() 输入数据中的调用有 1-3 个参数,不需要 必须用单引号引起来。
- 只应提取第一个参数。
- 第一个参数本身既不包含 , 也不包含 )

尝试以下应该适用于大多数平台的方法:

find . -name "*.php" -exec grep -sioh "__([^,)]*" {} + | cut -c 4-
  • -exec+ 确保执行尽可能少的 grep 调用(在大多数情况下,仅 1); {} 是匹配文件名的占位符。
  • 正如 中指出的那样,grep 正则表达式应该不那么贪婪,以确保捕获一行中的多个调用;此外,由于现在很清楚只应提取 1st 参数,因此 [^,)]* 用于仅捕获下一个参数或右括号。 (请注意,如果第一个参数本身包含逗号或括号,这仍然可能失败)。
  • cut 命令从 grep 的输出中删除不需要的部分(去除 __( 前缀)。

如果您的 grep 实现支持 -R(用于递归搜索)和 --include(将搜索的文件限制为匹配 glob 的文件),您可以使用

 grep -R --include '*.php' -sioh "__([^,)]*" . | cut -c 4-

如果您的 grep 实现还支持 -P(PCRE:Perl 兼容的正则表达式),请使用 的修改版本:

 grep -R --include '*.php' -siohP "__\(\K[^,)]*"

使用 -P 通过附加 前瞻断言 ((?=...)) 可以更容易地使正则表达式更健壮,以确保捕获的令牌确实是后跟文字 ,).

 grep -R --include '*.php' -siohP "__\(\K[^,)]*(?=[,)])"

最后,请注意 grep-P 如何要求 \( 匹配文字 (,而非 -P grep 命令上面使用 basic 正则表达式,其中 (not 特殊的并且被视为文字(在那里,你必须使用 \( 让它们变得特别)。

在没有 -P 的 grep 实现中,调用 grep 作为 egrep 或使用 -E 激活对 extended 正则表达式的支持,后者具有更多功能和语法更接近 PCRE,但没有那么强大。


关于便携性的说明:

  • -P(支持 PCRE == Perl 兼容正则表达式)是 GNU grep 扩展(在 BSD grep 中不起作用)。
  • -o 是(至少)GNU grep 和 BSD grep 中的一个扩展。
  • -R--include 是(至少)GNU grep 和 BSD grep 中的扩展。