2

I have written this simple script for matching in shell script

file_name="xyz_abc_diagnostics.wifi2.2015-07-30.12-30-52.tar.gz"
chk_regex=".*\.\d+\-\d+\-\d+\.\d+\-\d+\-\d+.*"
if [[ "$file_name" =~ $chk_regex  ]];then
echo "in obs regex"
else
echo "dont triggered"
fi

I have checked this regex in java and here it is working fine. my syntax is right because when i use

.*

it is working fine. For shell script regex testing i have use this site http://regexraptor.net/ to check it also don't matching but in https://regex101.com/ which uses java regex it matches. I am not able to understand why it is failing in shell script. Is there any difference in shell script regex?If yes then please suggest me what changes i have to make

2 Answers 2

4

It is wrong to assume that all flavours of regex are the same. In this case, \d is not supported by bash regular expressions. You should change your regex to this:

chk_regex='\.[0-9]+-[0-9]+-[0-9]+\.[0-9]+-[0-9]+-[0-9]+'

Of course, this assumes that when you say \d you don't require anything more than the digits from 0 to 9, as opposed to anything considered to be a digit in your locale. If you want to also match characters outside this range, then [[:digit:]] is probably what you want, instead of [0-9].

If you don't require parameter expansion, it's generally a good habit to use ' rather than ".

I have also removed the leading and trailing .* (as they don't do anything useful) and un-escaped the - (thanks for the comment gniourf_gniourf).

Working example:

$ file_name="xyz_abc_diagnostics.wifi2.2015-07-30.12-30-52.tar.gz"
$ chk_regex='\.[0-9]+-[0-9]+-[0-9]+\.[0-9]+-[0-9]+-[0-9]+'
$ if [[ "$file_name" =~ $chk_regex  ]];then
> echo "in obs regex"
> else
> echo "dont triggered"
> fi
in obs regex

As you can see, the pattern matches, so the if branch is taken.


As mentioned in the comments, you can use globs to match this pattern as well:

[[ $file_name = *.+([[:digit:]])-+([[:digit:]])-+([[:digit:]]).+([[:digit:]])-+([[:digit:]])-+([‌​[:digit:]])* ]]

Granted, it's longer to write but globs may be useful if you wanted to loop through files matching this pattern, for example:

for archive in *.+([[:digit:]])-+([[:digit:]])-+([[:digit:]]).+([[:digit:]])-+([[:digit:]])-+([‌​[:digit:]])*
do
    # some stuff
done

Note that in the example containing a loop (and in both examples on older versions of bash) you will need to enable extended globs using shopt -s extglob.

Sign up to request clarification or add additional context in comments.

4 Comments

Now thinking about it, the glob looks longer and awkward, but you can use a variable to hold some parts of it: ds=+([[:digit:]])-+([[:digit:]])-+([[:digit:]]) and then [[ $file_name = *.$ds.$ds* ]].
@gniourf_gniourf I was considering the same, although I guess at that point you're swapping one line for two. I'll leave the decision up to the OP :)
You also need shopt -s extglob in some versions of bash. I can never remember when that became the default inside [[ ... ]].
@chepner [[ ... ]] is parsed as an extended glob since 4.1.
2

Here is a fix, use [0-9] class instead of a \d and use {2} limiting quantifier to make it shorter (and really, the leading/trailing .* are useless since you are not using the matched string, just check for presence):

#!/bin/bash
file_name="xyz_abc_diagnostics.wifi2.2015-07-30.12-30-52.tar.gz"
chk_regex="(\.[0-9]+(-[0-9]+){2}){2}"
if [[ "$file_name" =~ $chk_regex  ]];then
echo "in obs regex"
else
echo "dont triggered"
fi

See IDEONE demo

Result: in obs regex

2 Comments

@gniourf_gniourf: Thank you. I still wonder why IDEONE showed the right message when using $-prepended variable names.
Because both variables were unset (so expanded to the empty string), and the test boiled down to: [[ '' =~ '' ]] which is true. Try it: [[ "$nonexistent" =~ $nonexistent ]] && echo yes.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.