2013-03-12 22 views
5

Ho un file di testo che contiene sia testo e numeri, voglio usare grep per estrarre solo i numeri di cui ho bisogno per esempio, dato un file come segue:come estrarre sottostringa e numeri solo con grep/sed

miss rate 0.21 
ipc 222 
stalls n shdmem 112 

Quindi dire che voglio solo estrarre i dati per miss rate che è 0.21. Come posso farlo con grep o sed? Inoltre, ho bisogno di più di un numero, non solo di quello successivo a miss rate. Cioè, potrei voler ottenere sia 0.21 e 112. Un esempio di output potrebbe essere il seguente:

0.21 222 112 

Causa Ho bisogno dei dati per la trama successiva.

+0

Si consiglia di utilizzare sed invece di grep se questo funziona per voi –

+0

sed è accettabile anche se funziona in modo più elegante in questo caso. – Hooloovoo

risposta

3

Uso awk invece:

awk '/^miss rate/ { print $3 }' yourfile 

farlo con solo grep, è necessario estensioni non standard, come qui con GNU grep usando PCRE (-P) con lookbehind positiva (? < = ..) e solo match (-o):

grep -Po '(?<=miss rate).*' yourfile 
0

È possibile utilizzare:

grep -P "miss rate \d+(\.\d+)?" file.txt 

o:

grep -E "miss rate [0-9]+(\.[0-9]+)?" 

Entrambi questi comandi verranno stampati miss rate 0.21. Se vuoi estrarre solo il numero, perché non usare Perl, Sed o Awk?

Se proprio vuoi evitare quelli, forse funzionerà?

grep -E "miss rate [0-9]+(\.[0-9]+)?" g | xargs basename | tail -n 1 
1

Se davvero desidera utilizzare solo grep per questo, allora si può provare:

grep "miss rate" file | grep -oe '\([0-9.]*\)' 

Sarà in primo luogo trovare la linea che corrisponde, e poi solo in uscita le cifre.

Sed potrebbe essere un po 'più leggibile, però:

sed -n 's#miss rate ##p' file 
4

Utilizzando il trucco speciale sguardo intorno regex \K con motore con :

grep -oP 'miss rate \K.*' file.txt 

o con :

perl -lne 'print $& if /miss rate \K.*/' file.txt 
+0

Aggiunta soluzione portatile Perl =) –

+0

il trucco \ K è davvero utile. Sì, preferisco grep per farlo poiché non sono un esperto di awk e anche un prob con awk è il separatore di campo poiché il testo in un singolo campo può avere spazi multipli e variabili come in "miss rate XX" e "stalls total" numero XXX ' – Hooloovoo

4

La soluzione grep -e- cut sarebbe simile:

per ottenere il 3 ° campo per un utilizzo grep di successo:

grep "^miss rate " yourfile | cut -d ' ' -f 3 

o per ottenere il 3 ° campo e l'utilizzo resto:

grep "^miss rate " yourfile | cut -d ' ' -f 3- 

Oppure, se si utilizza bash e "tasso di miss" si verifica solo una volta nel file si può anche solo fare:

a=($(grep -m 1 "miss rate" yourfile)) 
echo ${a[2]} 

dove ${a[2]} è il vostro risultato.

Se "tasso di errore" si verifica più di una volta, è possibile eseguire il ciclo sull'output di grep leggendo solo ciò che è necessario. (In bash)

0

Credo

sed 's|[^0-9]*\([0-9\.]*\)|\1 |g' fiilename

farà il trucco. Comunque ogni voce sarà sulla propria linea se è ok. Sono sicuro che esiste un modo per sed di produrre una lista delimitata da virgola o spazio, ma io non sono un super padrone di tutte le cose sed.

Problemi correlati