Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

how to get the first number of variables

I have a variable:

STR="My horse weighs 3000 kg but the car weighs more"
STR="Maruska found 000011 mushrooms but only 001 was not with meat"
STR="Yesterday I almost won the lottery 0000020 CZK but in the end it was only 05 CZK"

I need to get the numbers:

3000
11
20

Please advise anyone?

share|improve this question

migrated from serverfault.com Sep 24 '13 at 19:28

This question came from our site for professional system and network administrators.

6 Answers 6

With gawk, set the record separator RS to a sequence of digits. The text that matched the RS pattern can be retrieved viaRT. Add 0 to RT to force it to a number (thus dropping the leading zeroes). Exit as soon as the first instance is printed

awk -v RS=[0-9]+ '{print RT+0;exit}' <<< "$STR"

Or here is a bash solution

shopt -s extglob
read -r Z _ <<< "${STR//[^[:digit:] ]/}"
echo ${Z##+(0)}
share|improve this answer
    
Nice. Do you care to elaborate? –  jasonwryan Sep 24 '13 at 20:43
    
@jasonwryan, thanks. Just did –  1_CR Sep 24 '13 at 21:02

Here is one way to do it:

echo $STR | grep -o -E '[0-9]+' | head -1 | sed -e 's/^0\+//'

Test:

$ STR="My horse weighs 3000 kg but the car weighs more"
$ echo $STR | grep -o -E '[0-9]+' | head -1 | sed -e 's/^0\+//'
3000

$ STR="Maruska found 000011 mushrooms but only 001 was not with meat"
$ echo $STR | grep -o -E '[0-9]+' | head -1 | sed -e 's/^0\+//'
11

$ STR="Yesterday I almost won the lottery 0000020 CZK but in the end it was only 05 CZK"
$ echo $STR | grep -o -E '[0-9]+' | head -1 | sed -e 's/^0\+//'
20
share|improve this answer

If your implementation of grep doesn't have -o or if you're not using Bash, you can do the following:

printf "%.0f\n" $(printf "%s" "$string"|sed  's/^[^0-9]*//;s/[^0-9].*$//')
share|improve this answer
#!/bin/bash

string="My horse weighs 3000 kg but the car weighs more"

if [[ $string =~ ^([a-zA-Z\ ]*)([0-9]*)(.*)$ ]]
then
    echo ${BASH_REMATCH[1]}
fi  
share|improve this answer
1  
The subscript should be 2 instead of 1. But you really don't need that complex of a regex. It would fail anyway if there were other characters in the string. –  Dennis Williamson Sep 25 '13 at 1:08

I've put your strings in an array so it can easily be iterated for this demonstration.

This uses Bash's builtin regular expression matching.

Only a very simple pattern is required. It's recommended to use a variable to hold the pattern instead of incorporating it directly in the match test. It's essential for more complex patterns.

str[0]="My horse weighs 3000 kg but the car weighs more"
str[1]="Maruska found 000011 mushrooms but only 001 was not with meat"
str[2]="Yesterday I almost won the lottery 0000020 CZK but in the end it was only 05 CZK"

patt='([[:digit:]]+)'

for s in "${str[@]}"; do [[ $s =~ $patt ]] && echo "[${BASH_REMATCH[1]}] - $s"; done

I included the square brackets only to visually set off the numbers.

Output:

[3000] - My horse weighs 3000 kg but the car weighs more
[000011] - Maruska found 000011 mushrooms but only 001 was not with meat
[0000020] - Yesterday I almost won the lottery 0000020 CZK but in the end it was only 05 CZK

To get the numbers without the leading zeroes, the easiest way is to force a base-10 conversion.

echo "$(( 10#${BASH_REMATCH[1]} ))"

Substituting that, the output looks like what you requested:

3000
11
20
share|improve this answer

Look up regular expressions and man grep.

echo $STR | grep -o [0-9]*

and to remove the leading zeros, treat it as a number:

LIT=$(echo $STR | grep -o [0-9]*)
VAL=$(expr $LIT + 0)
echo $VAL
share|improve this answer
    
Your solution fails with variables contains two number or the number padding zero. –  cuonglm Sep 24 '13 at 18:51
    
Thank you very much ;-) –  Veronika Lipská Sep 24 '13 at 18:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.