2012-10-19 21 views
13

Un'altra domanda per gli esperti di sed.Estrarre numeri da una stringa utilizzando espressioni regolari e regolari

Ho una stringa che rappresenta un percorso che avrà due numeri in esso. Un esempio è:

./pentaray_run2/Trace_220560.dat 

Ho bisogno di estrarre il secondo di questi numeri - vale a dire 220.560

ho (con qualche aiuto dai forum) stato in grado di estrarre tutti i numeri insieme (cioè 2.220.560) con :

sed "s/[^0-9]//g" 

o estrarre solo il primo numero con:

sed -r 's|^([^.]+).*$|\1|; s|^[^0-9]*([0-9]+).*$|\1|' 

ma quello che sto afte r è il secondo numero !! Qualsiasi aiuto molto apprezzato.

PS il numero che sto cercando è sempre il secondo numero nella stringa.

risposta

12

ok?

sed -r 's/.*_([0-9]*)\..*/\1/g' 

con il tuo esempio:

kent$ echo "./pentaray_run2/Trace_220560.dat"|sed -r 's/.*_([0-9]*)\..*/\1/g' 
220560 
+0

Grandi opere a meraviglia. Immagino che _ in là significhi cercare i numeri solo dopo il trattino basso? In questo caso posso sempre aspettarmi un carattere di sottolineatura, quindi funzionerà. Il vero bit dell'espressione lo fa. * _ StackOverflow è davvero una risorsa fantastica - sono rimasto sconcertato per ore. Interessante pensate che ci sia un modo per usare il \ 1 alla fine - magari estraete tutti i numeri (cifre contigue) come sottostringhe e chiedete il secondo. Questo potrebbe essere utile a me e ad altri in futuro? – Steven

6

Se grep è il benvenuto:

$ echo './pentaray_run2/Trace_220560.dat' | grep -oP '\d+\D+\K\d+' 
220560 

E più portatile con Perl con la stessa espressione regolare:

echo './pentaray_run2/Trace_220560.dat' | perl -lne 'print $& if /\d+\D+\K\d+/' 
220560 

penso l'approccio è più pulito & più robusto rispetto all'utilizzo sed

6

È possibile estrarre gli ultimi numeri con questo:

sed -e 's/.*[^0-9]\([0-9]\+\)[^0-9]*$/\1/' 

E 'più facile pensare che questo a ritroso:

  1. Dalla fine della stringa , corrisponde a zero o più caratteri non numerici
  2. Corrispondono (e acquisiscono) uno o più caratteri numerici
  3. Corrispondenza a almeno uno non sia una cifra carattere
  4. hanno tutte i caratteri a inizio della stringa

parte 3 della partita è dove la "magia" avviene, ma limita anche le partite di avere almeno un non -Digit prima del numero (es. non è possibile abbinare una stringa con un solo numero all'inizio della stringa, sebbene vi sia una soluzione semplice per l'inserimento di una cifra diversa all'inizio della stringa).

La magia è contrastare l'avidità da sinistra a destra dello .* (parte 4). Senza la parte 3, la parte 4 consumerebbe tutto il possibile, che include i numeri, ma con essa l'abbinamento fa in modo che si fermi per consentire almeno una cifra non seguita seguita da una cifra da consumare nelle parti 1 e 2, permettendo che il numero sia catturato.

5

Questo potrebbe funzionare per voi (GNU SED):

sed -r 's/([^0-9]*([0-9]*)){2}.*/\2/' file 

Questo estrae il secondo numero:

sed -r 's/([^0-9]*([0-9]*)){1}.*/\2/' file 

e questo estrae il primo.

Problemi correlati