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.
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:
Prova questo:
grep -oP '(?<=ID: )[0-9]+' file
o:
perl -nle 'print $1 if /ID:.*?(\d+)/' file
-o
e -P
sono estensioni GNU a grep
. -o
funziona anche su BSD. Il supporto PCRE con -P
non è sempre compilato neanche in.
Utilizzare egrep
con -o
o grep
con -Eo
opzione per ottenere solo il segmento corrispondente. Usa [0-9]
come regex per ottenere solo numeri:
grep -Eo [0-9]+ filename
Ci sono molti modi per farlo. Per esempio:
Usa GNU grep
con PCRE recenti e abbina i numeri dopo ID:
:
grep -oP 'ID:\s*\K\d+' file
Usa awk
e 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
Usa GNU grep con Extended Regular Expressions e analizzalo due volte:
grep -Eo '^ID: *[0-9]+' file | grep -o '[0-9]*'
\K
sta facendo nel primo esempio?
-o
stampare 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'
sed -n '/ID: 54376/,${s/[^ 0-9]*//g;/./p}'
Ciò stamperà solo tutti i numeri e gli spazi che si verificano dopo ID: 54376
in qualsiasi input di file.
Ho appena aggiornato un po 'quanto sopra per renderlo un po' più veloce con *
e non p
sfilare 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
/
/
.
{
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}'
54376
1 03 2
3 03 4
5 03 6
7 03 8
9 03 10
54376
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: //p
ha la forma s/pattern/repl/flags
- s
mezzi 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
Un altro comando GNU sed,
sed -nr '/ID: [0-9]+/ s/.*ID: +([0-9]+).*/\1/p' file
Stampa qualsiasi numero dopo ID:
+
. Se la differenza tra i personaggi un carattere e 3 è lo script potrebbe non funzionare in tutto sed
probabilmente 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]
.
Usa grep + awk:
grep "^ID" your_file | awk {'print $2'}
Bonus: facile da leggere :)
grep
se 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.