非交互式执行rgrep

时间:2011-08-10 16:35:55

标签: emacs

我正在尝试从一个小的Emacs Lisp实用程序运行rgrep命令,但是我得到了一个奇怪的错误。命令描述是:

  

rgrep是一个交互式编译的Lisp函数。

     

(rgrep REGEXP& optional FILES DIR CONFIRM)

     

以源自DIR的目录树中的FILES中的REGEXP递归grep。   搜索仅限于与shell模式FILES匹配的文件名。   FILES可以使用grep-files-aliases', e.g. entering ch'中定义的缩写等同于`*。[ch]'。

     

使用C-u前缀,您可以编辑构造的shell命令行   在执行之前。有两个C-u前缀,直接编辑和运行   `grep的找到的命令”。

     

在缓冲区中收集输出。虽然find可以异步运行,但您可以   使用C-x`(M-x next-error)或grep输出缓冲区中的RET来转到   发现grep匹配的行。

     

此命令与M-x lgrep和M-x共享参数历史记录   的grep-发现。

我试着跑:

(rgrep "something" "all" "~/projects/")

我得到了

 *** Eval error ***  Wrong type argument: stringp, nil

显然所有的参数都是字符串,所以我无法理解这个零来自哪里。

我在Debian测试中运行Emacs 23.3。

提前感谢您的帮助!

4 个答案:

答案 0 :(得分:4)

我认为这是因为你没有定义'grep-find-template'。这肯定是(已经调试过)为什么命令会在我的版本上产生错误。看看那个变量的帮助。

欢呼声。

PS。它是以交互方式调用它之间的区别..

"find . <X> -type f <F> -print0 | \"xargs\" -0 -e grep <C> -nH -e <R>"
交互式调用

..由'grep-calc-defaults'设置

PPS。我想你只需要小心你的电话。如果没有找到匹配项,您将收到“Grep异常退出代码123”错误。

mkdir -p ~/a/b
cp ~/.bash* ~/a/b
emacs -q

C-x b <RET> *scratch*
(grep-compute-defaults)
(rgrep "^.*\\?\=.*$" "*bash*" "~/a")

..很多比赛!

答案 1 :(得分:3)

当您以编程方式致电rgrep时,您收到此消息的原因是interactivegrep变种的grep-compute-defaults次调用interactive调用了(eval-after-load "grep" '(grep-compute-defaults)) {{1}}调用。当您以编程方式调用时,不会对此进行评估。

解决此问题的最简单方法是添加

{{1}}
在您的代码中

,这将强制调用它(但仅在需要时)。

答案 2 :(得分:2)

以下似乎对我有用:

(defadvice rgrep (around rgrep-init)
  "Init grep defaults before calling rgrep non-interactively."
  (when (not (called-interactively-p))
    (grep-compute-defaults))
  ad-do-it)

(ad-activate 'rgrep)

(rgrep "something" "all" "~/projects/")

答案 3 :(得分:1)

根据Emacs手册:

  

命令Mx lgrep(本地grep)和Mx rgrep(递归grep)是更加用户友好的grep和grep-find版本,它们分别提示正则表达式匹配,要搜索的文件和基本目录搜索。

对于手头的问题,我们不需要这种妨碍这种“用户友好性”的问题。我们可以使用简单的“grep”elisp函数,它更适合非交互式使用。基本上,无论您使用什么grep命令行来实现所需的结果,此函数都将参数作为参数。最大的灵活性!

以下是您的方案的样子:

(grep "grep --color -rn something ~/projects/")

这是grep选项的另一个更复杂的用法,只匹配Python文件中的完整单词:

(grep "grep --include=\"*.py\" --color -rnw your_pattern files_root_dir")