Regex, der Zahlen nach einer bestimmten Zeichenfolge abtastet


8

Also habe ich eine Zeile:

ID: 54376

Können Sie mir helfen, einen regulären Ausdruck zu erstellen, der nur Zahlen ohne "ID:" zurückgibt?

HINWEIS: Diese Zeichenfolge befindet sich in einer Datei.

Antworten:


13

Versuche dies:

grep -oP '(?<=ID: )[0-9]+' file

oder:

perl -nle 'print $1 if /ID:.*?(\d+)/' file

Vielen Dank für die Antwort, aber ich brauche nicht alle Nummern aus einer Datei, sondern nur eine Nummer, die nach ID auftritt:
— Blake Gibbs

Meine Antwort wurde aktualisiert.
— Cuonglm

1
Beachten Sie, dass -ound -PGNU-Erweiterungen zu sind grep. -ofunktioniert auch auf den BSDs. PCRE-Unterstützung mit -Pwird auch nicht immer kompiliert.
— Matt

4

Verwenden Sie diese Option egrepmit -ooder grepmit -Eo, um nur das übereinstimmende Segment abzurufen. Verwenden Sie [0-9]als Regex, um nur Zahlen zu erhalten:

grep -Eo [0-9]+ filename

1
Das OP muss erst nach einer bestimmten Zeichenfolge übereinstimmen. Siehe den Titel der Frage.
— Terdon

4

Es gibt viele Möglichkeiten, dies zu tun. Zum Beispiel:

  1. Verwenden Sie GNU grepmit aktuellen PCREs und stimmen Sie die folgenden Zahlen ab ID::

    grep -oP 'ID:\s*\K\d+' file
    
  2. Verwenden Sie awkund drucken Sie einfach das letzte Feld aller Zeilen, die mit beginnenID:

    awk '/^ID:/{print $NF}' file
    

    Dadurch werden auch Felder gedruckt, die keine Zahlen sind, um nur Zahlen zu erhalten, und nur im zweiten Feld verwenden

    awk '($1=="ID:" && $2~/^[0-9]+$/){print $2}' file
    
  3. Verwenden Sie GNU grep mit erweiterten regulären Ausdrücken und analysieren Sie es zweimal:

    grep -Eo '^ID: *[0-9]+' file | grep -o '[0-9]*'
    

Vielen Dank! Was \Kmacht das erste Beispiel?
— rnd_d

2
@rnd_d ist ein PCRE-Konstrukt (Perl Compatible Regular Expressions), das bedeutet, dass "alles ignoriert wird, was bis zu diesem Punkt übereinstimmt". Es wird wie ein Lookbehind verwendet. Ich kann damit -onur den passenden Teil drucken, aber auch Dinge verwerfen, an denen ich nicht interessiert bin. Vergleiche echo "foobar" | grep -oP "foobar"undecho "foobar" | grep -oP 'foo\Kbar'
— terdon

4
sed -n '/ID: 54376/,${s/[^ 0-9]*//g;/./p}'

Dadurch werden nur alle Zahlen und Leerzeichen gedruckt, die nach ID: 54376einer Dateieingabe auftreten.

Ich habe das Obige gerade ein wenig aktualisiert, um es ein wenig schneller zu machen *und keine pleeren Zeilen zu drucken, nachdem die nicht {numerischen, Leerzeichen} Zeichen entfernt wurden.

Es adressiert Zeilen von Regex /ID: 54376/ ,bis zum $letzten und s///entfernt darauf alle oder einige *Zeichen, die ^nicht gedruckt werden , [^ 0-9]*und pdruckt dann /keine /Zeile mit einem .verbleibenden Zeichen.

DEMO:

{
echo line 
printf 'ID: 54376\nno_nums_or_spaces\n'
printf '%s @nd 0th3r char@cter$ %s\n' $(seq 10)
echo 'ID: 54376'
} | sed -n '/ID 54376/,${s/[^ 0-9]*//g;/./p}'

AUSGABE:

 54376
1  03  2
3  03  4
5  03  6
7  03  8
9  03  10
 54376

1

Mit sed:

{
    echo "ID: 1"
    echo "Line doesn't start with ID: "
    echo "ID: Non-numbers"
    echo "ID: 4"
} | sed -n '/^ID: [0-9][0-9]*$/s/ID: //p'

Das -nist "standardmäßig nichts drucken", das /^ID: [0-9][0-9]*$/ist "für Zeilen, die diesem regulären Ausdruck entsprechen" (beginnt mit "ID:", dann 1 oder mehr Ziffern, dann Zeilenende), und das s/ID: //pist von der Form s/pattern/repl/flags- sbedeutet wir Ersetzen Sie das Muster "ID: "durch Ersetzungstext ""(leere Zeichenfolge) mithilfe des pFlags. Dies bedeutet "Diese Zeile nach dem Ersetzen drucken".

Ausgabe:

1
4

Es funktioniert nicht, wenn die ID in der Mitte einer Zeile vorhanden ist.
— Avinash Raj

Auch sollte es nicht, basierend auf meiner Lektüre der Frage. Und wenn Sie nicht versuchen, diesen Fall vorzeitig zu behandeln, wird der Code einfacher und portabler.
— Godlygeek

0

Ein weiterer GNU sed Befehl,

sed -nr '/ID: [0-9]+/ s/.*ID: +([0-9]+).*/\1/p' file

Es druckt eine beliebige Zahl nach ID:


Das brauchst du wirklich nicht +. Wenn der Unterschied zwischen einem Zeichen und 3 Zeichen darin besteht, dass Ihr Skript möglicherweise nicht in allen seds funktioniert , sollten Sie wahrscheinlich Folgendes tun : sed -n '/ID: \([0-9][0-9]*\).*/{s//\1/;s/.*[^0-9]//;/./p}'. Ihre Antwort verfehlt auch die erste ID: [0-9]in einer Zeile, die zwei Vorkommen von enthält ID: [0-9].
— Mikesserv

0

Verwenden Sie grep + awk:

  grep "^ID" your_file | awk {'print $2'}

Bonus: leicht zu lesen :)


1
Sie brauchen nicht, grepwenn Sie verwenden awk. awk '/^ID/ { print $2 }'macht das Gleiche und vermeidet Probleme mit der Grep-Zeilenpufferung . Es ist auch so ziemlich das Gleiche wie eine der Lösungen in @ terdons Antwort.
— Cas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.