2

I am having some trouble understanding how shell-command-on-region works. Sometimes the region is passed to command, sometimes not, as far as I can tell.

Suppose I have an emacs buffer with "word" in the region, then counting the region's length with wc:

shell-command-on-region wc

returns 0 1 4 , as it should. But other commands don't seem to receive the region as input. For instance, both

shell-command-on-region   echo

and

shell-command-on-region locate 

produce, respectively, an empty result and an error message ("locate: no pattern to search for specified").

Why is the region passed to the command in the first example and not in the second and third one?

stefano
  • 175
  • 3

1 Answers1

6

Why is the region passed to the command in the first example and not in the second and third one?

The region is passed in all three cases; but if the command you pass it to does nothing with its standard input, then you will not get a useful result.

i.e. You are effectively doing this:

printf word | wc
printf word | echo
printf word | locate

Note that the default key binding M-| is a mnemonic for the fact that you are piping the region as input to the command. That might make it easier to remember.


Edit:

I'm still wondering if there is an emacs command that calls a a command with the region as argument, though.

(defun my-shell-command-with-region-arg (command beginning end)
  "Prompt for a shell COMMAND, and use the region as an argument.

Buffer text from BEGINNING to END is passed as a single argument to COMMAND."
  (interactive (list (read-shell-command "Shell command: ")
                     (region-beginning)
                     (region-end)))
  (let ((region (buffer-substring-no-properties beginning end)))
    (shell-command (concat command " " (shell-quote-argument region)))))
phils
  • 50,977
  • 3
  • 79
  • 122
  • I see, I had indeed misunderstood the command, assuming it would pass the region as argument, not as stdin. What would be needed to have the region passed as argument then? – stefano Oct 16 '19 at 05:22
  • Since the command I am passing the region to is a bash script I wrote, I was able to fix it following the answer by @andy in this SX question: https://stackoverflow.com/questions/18761209/how-to-make-a-bash-function-which-can-read-from-standard-input. I'm still wondering if there is an emacs command that calls a a command with the region as argument, though. – stefano Oct 16 '19 at 06:08
  • I've added one to the answer. – phils Oct 16 '19 at 07:56
  • So, in this case, I needed something like xargs -I{} echo {} – Constantin Hong Mar 26 '24 at 06:19