Filter text through shell command in Emacs

There is a command in vi [m] ! , which allows me to pass text through a shell command - for example, sort or indent - - and return the filtered text to the buffer. Is there an equivalent in emacs?

+55
emacs text-editor elisp
Oct. 15 '08 at 22:41
source share
3 answers

You can select a region and enter `Cu M- | RET 'command, and it replaces the region with the output of the command in the same buffer due to the interactive shell-command-on-region prefix argument.

+98
Oct 16 '08 at 0:27
source share

I wrote this a few years ago, this could help you:

 (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))))) 

I found this feature very useful. If you find this useful, I suggest binding it to some function key for convenience, I personally use F3 :

 (global-set-key [f3] 'generalized-shell-command) 
+15
Oct. 16 '08 at 0:58
source share

Late editing . As far as I value upvotes, Jurta's answer is the way to go. And Greg hacked more accurately than mine.

I will leave it all here because it may be worth something, but ...




Mx shell-command-on-region , which by default is bound to M-| .




I see that this does not do what Rohit requested. Using Ch f shell-command-on-region shows that the desired behavior is available in the non-interactive version of the command (by setting the replace argument to non-nil). To do this, we must write a wrapper.

Try this (upload it to *scratch* and run Mx eval-buffer , if it works, copy it to the .emacs file):

 (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) ) 

And pay attention, as I say in the comments, that this is not a very spectacular thing. But I think it works.




For all readers who do not know how to choose a region:

  • Move the β€œpoint” (current cursor position) to one end of the area and use C-space to activate the β€œlabel”
  • Move the point to the other end of the area.
  • After doing this, call the command
+7
Oct. 15 '08 at 22:43
source share



All Articles