Regex che avrebbe grep i numeri dopo una stringa specifica


8

Quindi ho una linea:

ID: 54376

Potete aiutarmi a creare una regex che restituirebbe solo numeri senza "ID:"?

NOTA: questa stringa si trova in un file.

Risposte:


14

Prova questo:

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

o:

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

Grazie per la risposta, ma non ho bisogno di tutti i numeri di un file, ma solo un numero che si verifica dopo l'ID:
Blake Gibbs,

Aggiornato la mia risposta.
cuonglm,

1
Si noti che -oe -Psono estensioni GNU a grep. -ofunziona anche su BSD. Il supporto PCRE con -Pnon è sempre compilato neanche in.
Matt,

4

Utilizzare egrepcon -oo grepcon -Eoopzione per ottenere solo il segmento corrispondente. Usa [0-9]come regex per ottenere solo numeri:

grep -Eo [0-9]+ filename

1
L'OP ha bisogno che corrisponda solo dopo una stringa specifica. Vedi il titolo della domanda.
terdon

4

Ci sono molti modi per farlo. Per esempio:

  1. Usa GNU grepcon PCRE recenti e abbina i numeri dopo ID::

    grep -oP 'ID:\s*\K\d+' file
    
  2. Usa awke stampa semplicemente l'ultimo campo di tutte le righe che iniziano conID:

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

    In questo modo verranno stampati anche campi che non sono numeri, per ottenere solo numeri e solo nel secondo campo

    awk '($1=="ID:" && $2~/^[0-9]+$/){print $2}' file
    
  3. Usa GNU grep con Extended Regular Expressions e analizzalo due volte:

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

Grazie! Cosa \Ksta facendo nel primo esempio?
rnd_d,

2
@rnd_d è un costrutto Perl Compatible Regular Expressions (PCRE) che significa "ignora qualsiasi cosa abbinata a questo punto". È usato come un lookbehind, mi consente di -ostampare solo la parte abbinata ma scarta anche le cose che non mi interessano. Confronta echo "foobar" | grep -oP "foobar"eecho "foobar" | grep -oP 'foo\Kbar'
terdon

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

Ciò stamperà solo tutti i numeri e gli spazi che si verificano dopo ID: 54376in qualsiasi input di file.

Ho appena aggiornato un po 'quanto sopra per renderlo un po' più veloce con *e non psfilare le righe vuote dopo aver rimosso i caratteri non {numerici, spazio}.

Indirizza le linee da regex /ID: 54376/ ,fino $all'ultima e su di esse s///rimuove tutti o tutti i *caratteri, quindi ^non strappa alcuna linea con un carattere rimanente.[^ 0-9]*p//.

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}'

PRODUZIONE:

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

1

Usando 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'

Il -nè "non stampa nulla di default", il /^ID: [0-9][0-9]*$/è "per le linee corrispondenti a questi regex" (inizia con "ID:", quindi 1 o più cifre, quindi capolinea), e l' s/ID: //pha la forma s/pattern/repl/flags- smezzi che stai facendo un sostituto, per sostituire il modello "ID: "con testo sostitutivo ""(stringa vuota) usando ilp bandiera, che significa "stampa questa riga dopo aver fatto la sostituzione".

Produzione:

1
4

Non funzionerà se l'ID è presente al centro di una linea.
Avinash Raj,

Né dovrebbe, in base alla mia lettura della domanda. E non provare a gestire prematuramente quel caso rende il codice più semplice e portatile.
godlygeek,

0

Un altro comando GNU sed,

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

Stampa qualsiasi numero dopo ID:


Non hai davvero bisogno di +. Se la differenza tra i personaggi un carattere e 3 è lo script potrebbe non funzionare in tutto sedprobabilmente si dovrebbe fare: sed -n '/ID: \([0-9][0-9]*\).*/{s//\1/;s/.*[^0-9]//;/./p}'. La tua risposta manca anche la prima ID: [0-9]su una riga contenente due occorrenze di ID: [0-9].
Mikeserv,

0

Usa grep + awk:

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

Bonus: facile da leggere :)


1
Non hai bisogno grepse stai usando awk. awk '/^ID/ { print $2 }'fa la stessa cosa ed evita problemi di buffering della linea grep . È anche praticamente la stessa di una delle soluzioni nella risposta di @ terdon.
Cas
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.