I'm trying to format some text that matches a regexp using an external shell command. I've been able to use C-u M-| successfully on a region, but I can't figure out how to do that within replace-regexp.

I've tried using \,(shell-command-on-region point-min point-max "python -m json.tool") as the second argument to replace-regexp, but I get Error evaluating replacement expression: (void-variable point-min).

Is there a way to use replace-regexp with shell-command-on-region?

1 Answer 1


point-min and point-max are functions not variables. So try this instead:

(shell-command-on-region (point-min) (point-max) "python -m json.tool")

Is there a way to use replace-regexp with shell-command-on-region?

Yes, but not combining them properly is not what the error message is about. But I can see where your confusion is coming from: "Error evaluating replacement expression:". That's additional information intended to help you figure out in what context the void-variable error occurred. Unfortunately it did the opposite.

Edit: as pointed out in the comments there are a few more issues. I won't walk you though all of them; I suggest you read the documentation about the involved functions instead. But here is some code that should do the trick.

(let ((buf (generate-new-buffer " *temp*")))
  (shell-command-on-region (point-min) (point-max)
                           "python -m json.tool" buf)
  (with-current-buffer buf
    (goto-char (point-min))
    (replace-regexp "regexp" "replacement")
  (kill-buffer buf))
  • OP will likely run into a new error now because shell-command-on-region doesn't actually return a string, you would need additional code on top of it to get it to work with replace-regexp. Something like (with-temp-buffer (shell-command-on-region (point-min) (point-max) "command" (current-buffer)) (buffer-string)) Jun 11, 2015 at 13:08
  • Thanks for the help. I am seeing the issue Jordon mentioned though. It replaces all matches with 1, which I assume is the return value of shell-command-on-region
    – Connor
    Jun 11, 2015 at 13:23
  • @JordonBiondo's method works for replacing the text, but it seems point-min and point-max aren't what I need. The shell command is operating on an empty string even though the regexp is matching and replacing a selection.
    – Connor
    Jun 11, 2015 at 13:38
  • Silly mistake on my part, of course wrapping shell-command-on-region with with-temp-buffer means that it would be acting on the text of the new temp buffer which is empty. You'll have to do some fancier work. Which means you'll probably want to write a custom function to use in the replacement, or write a different command to use. You'd need to do something like this: (let ((buff (generate-new-buffer "*temp*"))) (shell-command-on-region (point-min) (point-max) "command" buff) (prog1 (with-current-buffer buff (buffer-string)) (kill-buffer buff))) Jun 11, 2015 at 13:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.