在Emacs中通过shell命令过滤文本

在vi [m]中有! 命令,让我通过shell命令pipe道文本 – 如sorting或缩进 – 并获取过滤的文本回到缓冲区。 在emacs中有没有相同的东西?

您可以select一个区域并键入Cu M- | 命令RET',并且由于shell-command-on-region的交互式前缀参数而使用同一缓冲区中的命令输出来replace该区域。

几年前我写了这个,它可能会帮助你:

 (defun generalized-shell-command (command arg) "Unifies `shell-command' and `shell-command-on-region'. If no region is selected, run a shell command just like Mx shell-command (M-!). If no region is selected and an argument is a passed, run a shell command and place its output after the mark as in Cu Mx `shell-command' (Cu M-!). If a region is selected pass the text of that region to the shell and replace the text in that region with the output of the shell command as in Cu Mx `shell-command-on-region' (Cu M-|). If a region is selected AND an argument is passed (via Cu) send output to another buffer instead of replacing the text in region." (interactive (list (read-from-minibuffer "Shell command: " nil nil nil 'shell-command-history) current-prefix-arg)) (let ((p (if mark-active (region-beginning) 0)) (m (if mark-active (region-end) 0))) (if (= pm) ;; No active region (if (eq arg nil) (shell-command command) (shell-command command t)) ;; Active region (if (eq arg nil) (shell-command-on-region pm command tt) (shell-command-on-region pm command))))) 

我发现这个function非常有帮助。 如果你觉得它有用,我build议绑定到一些function键为方便起见,我个人使用F3

 (global-set-key [f3] 'generalized-shell-command) 

迟到的编辑 :尽pipe我赞赏上涨,Jurta的答案是要走的路。 而格雷格的黑客比我的整洁。

我会在这里留下余下的,因为它可能是值得的,但是…


Mx shell-command-on-region ,似乎绑定到M-| 默认。


我看到这不是Rohit所要求的。 使用Ch f shell-command-on-region发现,在Ch f shell-command-on-region的非交互版本中(通过将参数replace为非零),可以获得所需的行为。 我们应该可以写一个包装来做到这一点。

试试这个(把它载入*scratch*并运行Mx eval-buffer ,如果有效的话,把它复制到你的.emacs文件中):

 (defun shell-command-on-region-replace (start end command) "Run shell-command-on-region interactivly replacing the region in place" (interactive (let (string) (unless (mark) (error "The mark is not set now, so there is no region")) ;; Do this before calling region-beginning ;; and region-end, in case subprocess output ;; relocates them while we are in the minibuffer. ;; call-interactively recognizes region-beginning and ;; region-end specially, leaving them in the history. (setq string (read-from-minibuffer "Shell command on region: " nil nil nil 'shell-command-history)) (list (region-beginning) (region-end) string))) (shell-command-on-region start end command tt) ) 

请注意,正如我在评论中所说的那样,这不是一个非常精明的事情。 但我认为它的作品。


对于不知道如何select地区的读者,

  1. 将“点”(当前光标位置)移动到该区域的一端,使用C-space激活“标记”
  2. 将点移到该区域的另一端
  3. 你完成了,调用命令