≡ Menu

Bash Shell: Extract Digits From a String

How do I extract digits only from a given string under Bash shell?

You can use the sed, grep and other shell utilities as follows:

 
grep -o "[0-9]" <<<"input"
 grep -o "[0-9]" <<<"$var"
 grep -o "[0-9]" <<<"test123"
 grep -o "[0-9]" <<<"1Th5is is a test. 5"
 var="foo1bar2"
 output=$(grep -o "[0-9]" <<<"$var")
 echo "$output"
 grep -oE "[[:digit:]]{1,}" input.file
 

See our grep command and grep regex tutorial for more information.

Tweet itFacebook itGoogle+ itPDF itFound an error/typo on this page?

{ 10 comments… add one }

  • Francis February 25, 2011, 1:15 am

    Try using ‘tr’, e.g.,
    $ echo ‘asd;lfj29834slkjajfds298124768ald;09290dsfasd098089adfs’ | tr -d [:alpha:] | tr -d [:punct:]
    2983429812476809290098089

    • Antonio Mendes March 30, 2011, 12:41 pm

      Or simply doing this:
      echo “ljhdfkldkfs23094823sdklnklsd23984nks8d8d8s” | tr -cd [:digit:]

      • Eric Sebasta June 9, 2015, 7:18 pm

        tr -cd [:digit:] #both more effective and easier to read +1

  • Cenk March 24, 2011, 2:33 pm

    Can we use regex in grep? For example, I only want to extract the http links for every line of my file. Is it possible?

    • Philippe Petrinko April 30, 2011, 12:43 pm

      Yes Cenk. RegEx are included.

      Read The Fantastic Manual, give it a try, and then share your results with us once you are done. Good reading.
      Looking forward to reading from you.

      GREP(1) User Commands GREP(1)

      NAME
      grep, egrep, fgrep, rgrep – print lines matching a pattern

      SYNOPSIS
      grep [OPTIONS] PATTERN [FILE…]
      grep [OPTIONS] [-e PATTERN | -f FILE] [FILE…]

      DESCRIPTION
      grep searches the named input FILEs (or standard input if no files are named, or if a single hyphen-minus (-) is given
      as file name) for lines containing a match to the given PATTERN. By default, grep prints the matching lines.

      In addition, three variant programs egrep, fgrep and rgrep are available. egrep is the same as grep -E. fgrep is the
      same as grep -F. rgrep is the same as grep -r. Direct invocation as either egrep or fgrep is deprecated, but is
      provided to allow historical applications that rely on them to run unmodified.

      OPTIONS
      Generic Program Information
      –help Print a usage message briefly summarizing these command-line options and the bug-reporting address, then exit.

      -V, –version
      Print the version number of grep to the standard output stream. This version number should be included in all
      bug reports (see below).

      Matcher Selection
      -E, –extended-regexp
      Interpret PATTERN as an extended regular expression (ERE, see below). (-E is specified by POSIX.)

      -F, –fixed-strings
      Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched. (-F is
      specified by POSIX.)

      -G, –basic-regexp
      Interpret PATTERN as a basic regular expression (BRE, see below). This is the default.

      -P, –perl-regexp
      Interpret PATTERN as a Perl regular expression. This is highly experimental and grep -P may warn of
      unimplemented features.

      Matching Control
      -e PATTERN, –regexp=PATTERN
      Use PATTERN as the pattern. This is useful to protect patterns beginning with hyphen-minus (-). (-e is
      specified by POSIX.)

  • Chris F.A. Johnson April 30, 2011, 11:42 am

    In bash, you don’t need any external command:

    var=1qa2ws3ed4rf
    printf "%s\n" "${var//[![:digit:]]/}"
    
    • Philippe Petrinko April 30, 2011, 12:50 pm

      Real cool Chris.
      I knew Brace Expansion tricks with search/replace pattern, but I never read [bash] accepted RegEx as a pattern. (It does not seem to be written into [bash] [man] page.
      Where did you read it first? That would be great to know. Bash-Hackers site ?

  • Philippe Petrinko April 30, 2011, 12:54 pm

    So I read here
    http://wiki.bash-hackers.org/syntax/pattern
    that bash patterns are not exactly equivalent to RegEx, but accepts POSIX character class, as you good remembered us.
    Thanks a lot, Chris, and thanks Vivek for his Fantastic Site!

    • Chris F.A. Johnson April 30, 2011, 1:32 pm

      Bash does not use regular expressions (execpt in [[ xxx =~ regex ]]); it uses filename expansion rules, which also accepts character classes.

      I could just as well have used [!0-9] instead of the character class:

      printf "%s\n" "${var//[!0-9]/}"
      
      • TheBonsai May 26, 2011, 5:49 am

        For digits usually okay, but for everything else it’s not recommended to use an explicit set like [A-Z] instead of [[:upper:]]

Leave a Comment