2016-06-01 14 views
1

Nach ein paar Stunden enttäuschter Suche kann ich das nicht herausfinden.Nur Übereinstimmung des ersten Auftretens der Ziffer

Ich bin Rohrleitung zu grep Eingang, was ich erhalten möchte ist das erste Vorkommen einer Ziffer.

Beispiel:

nmcli --version 
nmcli tool, version 1.1.93 

Rohr mit regex

nmcli --version |grep -o '[[:digit:]]' 

Output grep:

1 
1 
9 
3 

Was ich will:

1 

Ja gibt es einen Weg, um mit einem anderen Rohr zu tun, aber es ist „reine“ einzelne Regex, das zu tun?

+0

@trincot haben Sie sich die Mühe gemacht, das zu versuchen? '^' stimmt mit dem Anfang einer Zeichenfolge überein, nicht mit der ersten Instanz des folgenden Musters. –

+0

keine der Ziffern stehen am Anfang der Zeichenfolge @trincot. –

+0

'nmcli --version | awk -F [.] '{{$ 4 drucken}}? – Cyrus

Antwort

3

Mit GNU grep:

nmcli --version | grep -Po ' \K[[:digit:]]' 

Ausgang:

 
1 
Siehe

: Support of \K in regex

+0

Vielen Dank! Ich habe nur eine Frage dazu. Ist das reguläre Ausdruck-Metazeichen "pure" Regex-Ausdruck in der Welt? Vielleicht können wir das nicht anders machen, aber ich habe auf etwas wie "[[: digit:]]] gehofft?" (? Übereinstimmung 0 oder 1 Mal). Ist es möglich, oder muss dies mit besonderer Sorgfalt auf Metazeichen geschehen? – Marko

+0

Wenn Sie 'awk' (siehe andere Antwort) anstelle von' grep' verwenden, können wir das auf eine portabelere Weise tun. Aber mit 'grep' und ohne' head -1' zu verwenden, ist dies wahrscheinlich der beste Weg. Upsotting dies, wenn mein Stimmlimit in 2 Stunden zurückgesetzt wird :) – Will

-2

Sie könnten Standard verwenden awk statt:

nmcli --version | awk 'match($0, /[[:digit:]]/) {print substr($0, RSTART, RLENGTH); exit}' 

Zum Beispiel:

$ seq 11111 33333 | awk 'match($0, /[[:digit:]]/) {print substr($0, RSTART, RLENGTH); exit}' 
1 
+0

'nmcli --version | grep -o -m1 '[[: digit:]]' 'Es funktioniert nicht, aber mit seq ist es, auch 'awk' Beispiel ganze Zeile drucken ... – Marko

+1

Ihr 'm1'-Vorschlag funktioniert nicht. Trotz was das Handbuch impliziert, stoppt dies nach der ersten * Zeile *, die übereinstimmt, nicht nach dem ersten tatsächlichen Spiel. Es funktionierte nur mit Ihrem 'seq 7 10' Beispiel, weil' seq 7 10' 4 getrennte Zeilen zurückgibt, wobei jede Zahl 7 bis 10 auf einer anderen Zeile ist. –

+0

@PaulL Alles sollte jetzt richtig funktionieren. Ich habe es nicht mit realistischen Eingaben getestet, tut mir leid. – Will

1

Obwohl Sie einen anderen Prozess vermeiden wollen, es am einfachsten scheint nur eine head zu Ihrem bestehenden Befehl hinzufügen ...

grep -o [[:digit:]] | head -n1 
0
echo "nmcli tool, version 1.1.93" |sed "s/[^0-9]//g" |cut -c1 
1 

echo "nmcli tool, version 1.1.93" |grep -o '[0-9]' |head -1 
1 
0

Dies kann als Stream zu sehen Bearbeitungsaufgabe: Reduziere diese eine Zeile auf die erste Ziffer. Grund regex registerbasierte Referenzierung erreicht die Aufgabe:

$ echo "junk 1.2.3.4" | sed -e 's/.* \([0-9]\).*/\1/' 
1 

Traditionell ist Grep am besten für Dateien und Linien suchen, die einem Muster entsprechen. Aus diesem Grund erfordert die grep-Lösung die Verwendung von Perl regex; Perl Regex verfügt über Funktionen, die grep in Kombination mit -o erlauben, "out of the box" zu entkommen und so verwendet zu werden, wie es eigentlich nicht beabsichtigt war: passe X an, gebe aber einen Teilstring von X aus. Die Lösung ist knapp, aber Nicht portierbar für Grep-Implementierungen ohne PCRE.

Verwenden Sie [0-9], um ASCII-Ziffern übrigens anzupassen. Der Zweck von [[:digit:]] ist, Gebietsschema-spezifisches Verhalten einzubringen: um andere Ziffern als nur die ASCII 0x30 bis 0x39 abgleichen zu können.

Es ist ziemlich sicher zu sagen, dass nmcli wird nicht seine --version mit z. B. Devangari Ziffern, wie 1.2.3.4.