Bash: como obter o primeiro número que ocorre no conteúdo de uma variável

8

como obter o primeiro número de variáveis

Eu tenho uma variável:

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"

Eu preciso pegar os números:

3000
11
20

Por favor, avise alguém?

    
por Joseph R. 24.09.2013 / 20:31

6 respostas

6

Com o gawk, defina o separador de registro RS para uma sequência de dígitos. O texto que correspondeu ao padrão RS pode ser recuperado por meio de RT . Adicione 0 a RT para forçá-lo a um número (descartando assim os zeros iniciais). Saia assim que a primeira instância for impressa

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

Ou aqui está uma solução bash

shopt -s extglob
read -r Z _ <<< "${STR//[^[:digit:] ]/}"
echo ${Z##+(0)}
    
por 24.09.2013 / 21:56
5

Aqui está uma maneira de fazer isso:

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

Teste:

$ 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
    
por 24.09.2013 / 20:49
2

Se sua implementação de grep não tiver -o ou se você não estiver usando o Bash, faça o seguinte:

printf "%.0f\n" $(printf "%s" "$string"|sed  's/^[^0-9]*//;s/[^0-9].*$//')
    
por 24.09.2013 / 21:57
2
#!/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  
    
por 24.09.2013 / 21:08
2

Eu coloquei suas strings em uma matriz para que ela possa ser facilmente iterada para essa demonstração.

Isso usa a correspondência de expressão regular interna do Bash.

Apenas um padrão muito simples é necessário. É recomendado usar uma variável para manter o padrão em vez de incorporá-lo diretamente no teste de correspondência. É essencial para padrões mais complexos.

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

Eu incluí os colchetes apenas para compensar visualmente os números.

Saída:

[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

Para obter os números sem os zeros à esquerda, a maneira mais fácil é forçar uma conversão de base 10.

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

Substituindo isso, a saída se parece com o que você pediu:

3000
11
20
    
por 25.09.2013 / 03:02
1

Procure expressões regulares e man grep .

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

e para remover os zeros à esquerda, trate-o como um número:

LIT=$(echo $STR | grep -o [0-9]*)
VAL=$(expr $LIT + 0)
echo $VAL
    
por 24.09.2013 / 20:45

Tags