以递归方式搜索文件并获取与模式匹配的值

时间:2012-04-19 14:59:16

标签: regex grep

所以,我需要一些控制台工具(没有异国情调)或php功能,它执行以下操作。 (我不想编写自己的递归函数,例如使用file_get_contents())

我有一个带有几个子目录的目录。有些文件包含<?php ech $this->translate('string'); ?>,而字符串总是不同。

我如何制作一个与上述功能相匹配的模式,只返回字符串? Atm,我会选择grep和exec();获取我的字符串的第二个正则表达式。但可能,我可以做得更好。

我的grep示例:grep -r "$this[->]translate('.*')" dir

除了小问题:这有何不同:grep -r foo dirgrep -r foo dir/*

3 个答案:

答案 0 :(得分:2)

你可以只获得&#39;字符串&#39;与前瞻和后瞻断言: grep -rhoP "(?<=this->translate\(')[^']*(?='\))" dir

答案 1 :(得分:1)

从你的小问题开始:

  

这有何不同:grep -r foo dirgrep -r foo dir/*

第二个示例不会在以dir开头的.子目录内搜索(因为它们不会被glob匹配)。所以,如果你是一个如下所示的目录:

dir/
  .a_dotted_dir/
  a_visible_dir/

第一个示例将在.a_dotted_dir内搜索,而第二个示例则不会。

  

如何创建一个与上述函数匹配的模式,只返回字符串?

你不能,用grep本身。 Grep只匹配模式,但不对它们执行任何类型的处理。您可以通过列出与搜索模式匹配的文件并使用sed处理它们来完成您想要的任务,例如:

grep -rl "this->translate('.*')" dir |
  xargs sed -n "s/.*this->translate('\([^']*\)').*/\1/p"

另外,请注意我对正则表达式进行了一些更改。 [->]->不匹配,将$this置于双引号内最终将使用emptystring替换$this。您需要删除$,将其转义或使用单引号。

答案 2 :(得分:0)

  1. 使用方括号定义字符类,而美元符号将被shell解释为变量。你将不得不逃避他们的意思是正确的。我可能会这样做:

    echo "<?php echo \$this->translate('string'); ?>" \
      | grep -ho "\$this\s*->\s*translate('.*?')" 
      | sed "s/\$this->translate('\(.*\)')/\1/"
    

    \s代表

  2. grep -r <pattern> dirgrep -r <pattern> dir/*之间的差异有点微妙。

    在命令行上运行grep -r <pattern> dir/*时实际发生的是 shell 会将dir/*参数扩展到目录列表中。

    本质上:

    grep -rho <pat> dir/*
    

    相当于:

    grep -rho <pat> dir/a dir/b dir/c [etc...]
    

    其中'a','b'和'c'是目录/文件。所以grep将递归到每个目录dir中的所有文件,但不会递归到dotfiles或点目录。

    最好使用grep -rho <pat> dir,这会考虑所有文件。