Bash: So erhalten Sie die erste Zahl, die im Inhalt einer Variablen vorkommt

8

wie man die erste Anzahl von Variablen erhält

Ich habe eine 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"

Ich muss die Zahlen bekommen:

3000
11
20
Rui F Ribeiro
quelle

Antworten:

7

RSStellen Sie mit gawk das Datensatztrennzeichen auf eine Ziffernfolge ein. Der Text, der dem RSMuster entspricht, kann über abgerufen werden RT. Add 0to RT, um eine Zahl zu erzwingen (wodurch die führenden Nullen gelöscht werden). Beenden Sie das Programm, sobald die erste Instanz gedruckt wurde

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

Oder hier ist eine Bash-Lösung

shopt -s extglob
read -r Z _ <<< "${STR//[^[:digit:] ]/}"
echo ${Z##+(0)}
iruvar
quelle
Nett. Möchtest du das näher erläutern?
Jasonwryan
Ich verstehe es nicht Was mache ich falsch (mit der awk-Version)? gist.github.com/jamiejackson/d92750cc42442a527c6b94499a13bc79
Jamie Jackson
@ JamieJackson, stellen Sie sicher, dass Sie GNU awk aka gawk
iruvar
5

Hier ist eine Möglichkeit, dies zu tun:

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

Prüfung:

$ 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
cuonglm
quelle
Was ist der Zweck des sedam Ende? Es scheint, als hätten wir bereits das gewünschte Ergebnis, bevor es in sed geht.
Michael
Nein, Sie haben für # 2, 000011für die Sie die führenden Nullen entfernen müssen. Aber Sie könnten vereinfachen, indem Sie übereinstimmen, [1-9][0-9]*was die führenden Nullen von Anfang an entfernen würde: echo $STR | grep -o -E '[1-9][0-9]*'
CCH
2

Wenn Ihre Implementierung von Bash grepnicht hat -ooder Sie Bash nicht verwenden, können Sie Folgendes tun:

printf "%.0f\n" $(printf "%s" "$string"|sed  's/^[^0-9]*//;s/[^0-9].*$//')
Joseph R.
quelle
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  
philippe
quelle
1
Der Index sollte 2 statt 1 sein. Aber Sie brauchen diesen Komplex einer Regex wirklich nicht. Es würde sowieso fehlschlagen, wenn andere Zeichen in der Zeichenfolge wären.
Bis auf weiteres angehalten.
2

Ich habe Ihre Zeichenfolgen in ein Array eingefügt, damit sie für diese Demonstration problemlos wiederholt werden können.

Dies verwendet Bashs eingebauten Matching für reguläre Ausdrücke.

Es ist nur ein sehr einfaches Muster erforderlich. Es wird empfohlen, eine Variable zu verwenden, um das Muster zu halten, anstatt es direkt in den Übereinstimmungstest aufzunehmen. Es ist wichtig für komplexere Muster.

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

Ich habe die eckigen Klammern nur eingefügt, um die Zahlen visuell hervorzuheben.

Ausgabe:

[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

Um die Zahlen ohne die führenden Nullen zu erhalten, ist es am einfachsten, eine Basis-10-Konvertierung zu erzwingen.

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

Wenn Sie dies ersetzen, sieht die Ausgabe wie folgt aus:

3000
11
20
Bis auf weiteres angehalten.
quelle
1

Suchen Sie nach regulären Ausdrücken und man grep.

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

und um die führenden Nullen zu entfernen, behandeln Sie sie als Zahl:

LIT=$(echo $STR | grep -o [0-9]*)
VAL=$(expr $LIT + 0)
echo $VAL
Sven
quelle
Ihre Lösung schlägt fehl, wenn Variablen zwei Zahlen oder das Auffüllen der Zahlen Null enthalten.
Cuonglm