0

I am trying to do a bash script to check if input file name is of format name.json. The regx in bash doesn't work but it works with grep.

file t1.sh

echo "$1"
regx="^[\w\d-]+[.]json$"
echo $regx
[[ $1 =~ $regx ]] && echo "match" || echo "No Match"
echo $1 | grep -P $regx
test=$(echo $1 | grep -P $regx)
[[ -z $test ]] && echo "Grep No match" || echo "Grep match"

Output

$ ./t1.sh test-file.json
test-file.json
^[\w\d-]+[.]json$
No Match
test-file.json
Grep match
$ ./t1.sh test-file123.json
test-file123.json
^[\w\d-]+[.]json$
No Match
test-file123.json
Grep match
$ ./t1.sh test-file$.json
test-file$.json
^[\w\d-]+[.]json$
No Match
Grep No match

Why is bash not able to process any meta-characters? I thought quoting the regx solved the issue of escape characters.

preetam
  • 117
  • Always paste your script into https://shellcheck.net, a syntax checker, or install shellcheck locally. Make using shellcheck part of your development process. – waltinator Nov 03 '23 at 02:21
  • @waltinator, would that help here? I don't see shellcheck output anything about the regex issue. – ilkkachu Nov 03 '23 at 09:52

2 Answers2

3

As the comments hint, there are multiple different incompatible ways that people have chosen to implement regular expressions. The fine bash manual points you to the regex manual in section 3, which points you to the regex manual in section 7. Reading that tells you that [\w\d-] will match one of the three characters w d -.

Using [[:alnum:]-] in place of [\w\d-] will do what you appear to want to do.

icarus
  • 17,920
  • 1
    Minor correction: in bash (and anything else that uses POSIX "extended" regex syntax) [\w\d-] will also match a backslash character. – Gordon Davisson Nov 03 '23 at 07:33
0

As otherwise mentioned, there are different implementations of/extensions to regex in different tools.

If grep -P does what you want (FYI the switch you have used enables Perl Compatible Reg Ex features, not usually present in grep), then just use that. In your example it would be better implemented as follows:

grep -Pq "$regx" <<< "$1" && echo "Grep No match" || echo "Grep match"
bxm
  • 4,855