0

A number of my bash scripts need tidying up before sending them round. One of the thing I would like to do is to use curly braces for all variable names. So everywhere it says $PWD should be changed into ${PWD} et cetera.

As a test I use the code

PATH=${PWD}
PATH_PATH=$PATH
PATH_PATH_PATH=$PATH_PATH

My idea was to use regexp search and replace in emacs. The best expression that finds all my variable names (with CTRL-ALT-S) is $[A-Za-z0-9_\-]*, so a sequence of 'a' through 'z', 'A' through 'Z', '0' through '9', underscore or hyphen following a '$'. Also, it leaves the already-braced variable names alone.

Now replace:
In the manual it says that replace is 'M-% string RET newstring RET'. On my computer 'M-%' is 'ESC-%'. Regexp replace is given as 'C-M-% regexp RET newstring RET'. I guess that would be C-ESC-% for me? Unfortunately, that is also the shortcut for the 'system activity' monitor in KDE.

I'm left with 2 questions now:

  1. is there another way to invoke regexp replace than C-ESC-%
  2. for the excmple above, what should be the expression for 'newstring'?

1 Answer 1

1

I would use the regexp [$]\([a-zA-Z0-9_-]+\) and the replacement string ${\1}. Here's an explanation for my changes to your regexp:

  • The character $ matches the "end of line" position, so you need to escape it when matching a literal $. Using [$] instead of \$ is a matter of taste (and it cuts down on backslashes that might need to be escaped if you want to translate this to elisp).

  • You don't need to backslash-escape - inside the character alternative, and indeed you can't; including the backslash just matches backslashes too. From the manual:

    As a ‘\’ is not special inside a character alternative, it can never remove the special meaning of ‘-’ or ‘]’. So you should not quote these characters when they have no special meaning either. This would not clarify anything, since backslashes can legitimately precede these characters where they have special meaning, as in ‘[^\]’ (‘"[^\\]"’ for Lisp string syntax), which matches any single character except a backslash.

    But - will match itself when used inside a character alternative, as long as it can't be interpreted as part of a range. To be safe, put it first or last.

  • I think you don't want to match a lone $, so you should use + instead of *. Probably not too big a deal, though.

  • Finally, you need to wrap the variable name in \( \) so you can reference it in the replacement string (as \1).

As to your second question, you have several options:

  • The most straightforward option is ESC C-%. Note that ESC isn't a modifier key, it's a prefix key.

  • You could use the fact that Emacs interprets ESC and C-[ identically and use C-[ C-%.

  • You could invoke the command by name as M-x query-replace-regexp.

  • Or you could bind the command to a more convenient key in your personal configuration.

1
  • Thanks - that is fantastic! I found the regexp search documentation, but your ${\1} for replacing was missing - just what I needed. Also thanks for improving the regexp - I escaped the hyphen by default as it is used for ranges (like 'A-Z') so: interpreted. Very powerful stuff
    – alle_meije
    May 13, 2016 at 8:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .