2

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?

1
  • 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, 2014 at 18:33

3 Answers 3

5

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
   ;;
esac
2
  • Good answer. I knew about the backtick/backquote form of command substitution, but I had forgotten about the $() form.
    – Arkanon
    Sep 12, 2014 at 18:31
  • @Arkanon: `` is old-style; $() is cleaner.
    – sds
    Sep 12, 2014 at 18:47
0

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
fi

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.

0

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")
fi

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .