bashglob

How to get only the digits from a bash variable?


In the bash script below I want to get only the digits and only the letters from a variable that has both.

#!/usr/bin/env bash
set -eu

both="abc-123"
letters=${both//[^a-zA-Z]*/}
# digits=$(echo "$both" | sed -e 's/[^0-9]//g')   # works, but I want this in bash
digits=${both//[^0-9]*/}
echo "From $both: letters $letters, digits $digits."

When I run this, it prints:

From abc123: letters abc, digits .

Why does digits end up empty with bash 5.2.37(1)-release (aarch64-apple-darwin23.4.0)?


Solution

  • Why does digits end up empty

    The glob expression [^0-9]* matches a non-digit character [^0-9] and then matches any count of any characters *. Just like echo [^0-9]* would match a file named abc-123.

    How to get only the digits from a bash variable?

    Remove the erroneous *.

    digits=${both//[^0-9]/}