0

We want to know about the correct method for matching some variable name(including its $ prefix) via using the grep -E option.
It seems that this grep macthing function can only work with either no any option or -e option ......

> 
> 
> grep ""'$'status"" /home/ewpadm/.sapenv_wzwms1.csh
if ( $status == 0 ) then
if ( $status == 0 ) then 
    set rc1 = $status
    set rc2 = $status
    set rc3 = $status
    set rc4 = $status
    set rc5 = $status
    set rc6 = $status
    set rc7 = $status
    set rc8 = $status
> 
> 
> grep -E ""'$'status"" /home/ewpadm/.sapenv_wzwms1.csh
> 
> 
> grep -E """'$'status"""" /home/ewpadm/.sapenv_wzwms1.csh
> 
> 
> grep -e ""'$'status"" /home/ewpadm/.sapenv_wzwms1.csh 
if ( $status == 0 ) then
if ( $status == 0 ) then 
    set rc1 = $status
    set rc2 = $status
    set rc3 = $status
    set rc4 = $status
    set rc5 = $status
    set rc6 = $status
    set rc7 = $status
    set rc8 = $status
> 
> 
> grep -e "= "'$'status"" /home/ewpadm/.sapenv_wzwms1.csh
    set rc1 = $status
    set rc2 = $status
    set rc3 = $status
    set rc4 = $status
    set rc5 = $status
    set rc6 = $status
    set rc7 = $status
    set rc8 = $status
> 
>  
lylklb
  • 303

1 Answers1

3

$ is a special character for both the shell (where it's used to introduce some expansions such as $param, $(cmdsubst), $((arithmetic))) and for regular expressions (in all of basic, extended (-E, formerly egrep), perl (-P / -X perl / --perl-regexp...), augmented (-X/ --augmented-regexp)) where it means to match at the end of the subject, so you need to escape it for both, preferably with '...' for shells and with \$ or [$] in regular expressions (\ and [...] are also special in most shells and can also be quoted with '...'):

In basic RE (without -E/-P/-X...), $ is only special at the end of the regexp or in some cases before a \) so here the regexp can be $status, while in other regexp variants including extended ones, it's generally always special so the regexp must be \$status or [$]status.

Using the -F option of grep (formerly fgrep) for fixed strings avoid having to do the regexp escaping. perl-like regexps also have \Q...\E for quoting. So, many options:

grep -F '$status'
grep    '$status'
grep    '\$status'
grep    '[$]status'
grep -E '\$status'
grep -E '[$]status'

Non-standard:

grep -P '\$status'
grep -P '[$]status'
grep -P '\Q$status\E'
grep -X '\$status'
grep -X '[$]status'

In some shells, \ and " can also be used as quoting operators, but backslash and $ are often still special within "...", so that would make it awkward here. '...' are the strongest quotes (and in some shells such as rc and derivatives, the only quotes), so are the ones you generally want to use around regexp where many of the operators (^$*?\[](){}|) also happen to be special in the syntax of most shells.

In any case, those will also find $status inside

  • $status2, $status_old or $statusing
  • $$status ($$ followed by status)
  • \$status or any csh quoting where $status is taken literally

And will not find

  • ${status}
  • ${status[1]} (subscripting)
  • ${status:q} (modifiers)
  • $#status or ${#status} (number of words)
  • $%status or ${%status} (number of characters)
  • @ status++ / if ( status == 0 ) then (maths expressions where the variable may (sometimes) be used without a $ prefix).

Using a word boundary operator (\b in perl or augmented regexp, \b, \> or [[:>:]] in some implementations of BRE or ERE as non-standard extensions) would help with the first category of issues:

grep -P '\$status\b'

Without word boundary, that can be done by hand:

grep -E '\$status([^_[:alnum:]]|$)'
grep    '$status\([^_[:alnum:]].*\)\{0,1\}$'

Where we look for $status followed by either a character non-constituent of a variable name or the end of the line, or in BRE that don't have an alternation operator¹ but these days have \{0,1\} as an equivalent of ERE ?, $status optionally followed by a non-variable-constituent and any number of characters up to the end of the line.

To address a few more:

grep -P '\$\{?[#%]?status\b'
grep -E '\$\{?[#%]?status([^_[:alnum:]]|$)'
grep    '${\{0,1\}[#%]\{0,1\}status\([^_[:alnum:]].*\)\{0,1\}$'

¹ Though some grep implementations have \| for that as a non-standard extension.

  • I think that I should necessarily use the double quotes with -E option because I also need its matching pattern for the OR operator, i.e. -E "A|B". – lylklb Jun 14 '23 at 00:01
  • @lylklb, no single quotes are fine as well to escape |. See edit. – Stéphane Chazelas Jun 14 '23 at 05:27
  • Thanks ! We have verified that the single quotes with -E option can also work fine as 'A|B'. So it seems that there is almost no difference between the two type of quotes with -E option! – lylklb Jun 15 '23 at 12:36