I'm writing a bash script and I need to check if a file name has a number at the end (after a period) and if so get it, but I can't figure out how to use regex on a variable or string.

I was able to use echo in the terminal to pipe a string into grep, like this:

 echo "filename.txt.123" | egrep -o "\.[0-9]+$" | egrep -o "[0-9]+"

But I need to assign the output of this to a variable. I tried doing this:

 revNumber= echo "filename.txt.123" | egrep -o "\.[0-9]+$" | egrep -o "[0-9]+"

But that doesn't work. I tried a bunch of other things as well, but nothing was valid.

In my bash script I want to use grep on a variable and not a string, but the concept here is the same.

How can I use grep on a string or variable and then save the result into another variable?

  • can't backquotes solve it.. that's the syntax for getting the output of a command into a variable. r=`echo abc` echo $r – barlop Sep 12 '14 at 18:33

To assign the output of a command to a variable, use $():

revNumber=$(echo "filename.txt.123" | egrep -o "\.[0-9]+$" | egrep -o "[0-9]+")

If all you care about is matching, you might want to consider case:

case foo in
  f*) echo starts with f
  *) echo does not start with f
  • Good answer. I knew about the backtick/backquote form of command substitution, but I had forgotten about the $() form. – Arkanon Sep 12 '14 at 18:31
  • @Arkanon: `` is old-style; $() is cleaner. – sds Sep 12 '14 at 18:47

Why the grep and echo I/O overkill, I'd suggest using bash string processing capabilities:

TESTFNAME="filename.txt.283" # you can collect this from doing an ls in the target directory

# acquire last extension using a regexp, including the '.':
FEXT=$(expr "$TESTFNAME" : '.*\(\.[[:digit:]][[:digit:]]*\)')

# check if length is more than just the dot, that means we've got digits:
if [  ${#FEXT} -gt 1 ]; then
    echo "Gotcha!" $testFilename ${#FEXT} $FEXT # do whatever you like with the file

The regex can be optimized and isn't perfect, but here are the basics:

  • .* at the beginning will search at the end of the file.
  • [[:digit::]] is almost the same as [0-9], but I find it more readable

Check out other bash string manipulation capabilities at TLDP here.


The below is another option that uses a bash regex comparison before extracting the value at the end of the string.

if [[ $TESTFNAME =~ \.[0-9]+$ ]]; then
  VAL=$(egrep -o '[0-9]+$' <<<"$TESTFNAME")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.