using ripgrep with regex including literal dollar symbol

Suppose I have a script containing something like

VAR=${VAR1%.*}

I’m looking for a command along the lines of

rg "${.*%"

to find it, but I can’t get anywhere near.

all of these fail

rg "${.*%"
rg ${.*%
rg "${.*%"
rg ${.*%
Asked By: njamescouk

||

$, are special to regular expressions and to the shell (including within double quotes for the latter). { is also special to the shell in some contexts, the list of which varies with the shell.

In fact, a lot of the regexp operators (*, ?, |, {, }, (, ), , ^, $, [ and ] at least) are also special in the shell syntax (some shells anyway), so it’s good practice to enclose regexps inside single quotes inside which, in most shells, all characters lose their special meaning if any.

So:

rg '${.*%'

Where '...' escapes all characters for the shell (of those, (quoteing operator), $ (expansion operator) and * (glob operator) are special, sometimes % (job expansion operator)) and escapes the $ and { for the regexp.

Alternatively:

rg '[$][{].*%'

rg understands perl-like regular expressions for which {x,y} is a special operator like in modern extended regular expressions. Beware however that in basic regular expressions as understood by grep without -E/-P/-A/-X, {/} are not special but {, } are! So you must not escape the {/} of them to be treated literally in grep (or sed/ed/ex/vi… by default).

You may want to change your regexp to:

rg '${[^}]*%'

Where we replaced . (matches any single character), with [^}] (matches any single character other than }) for it to avoid matching inside:

Item ${foo} is 20% cheaper than item ${bar}

For instance.

Looking at your attempts:

  • rg "${.*%", that’s the same as rg '${.*%' in most shells, as is used by the shell to remove its special meaning to $ there. is kept in front of { and * as those characters are not special inside doubles quotes.
  • rg ${.*%, same as rg '${.*%'. outside of quotes is just another quoting operator. x is like 'x' (newline, and sometimes ` and ! being special cases). In the fish shell, can also be used for n, t, a, 377… escape sequences.
  • rg "${.*%", same as rg '${.*%', that was close
  • rg ${.*% would be the worse one as the * globbing operator ends up being unquoted so the shell could expand it to the list of files whose name starts with ${ and ends in % in the current working directory.
Answered By: Stéphane Chazelas