2013-03-12 15 views
5

ich eine Textdatei haben sowohl Text als auch Zahlen enthalten, möchte ich grep verwenden nur die Zahlen, die ich brauche zum Beispiel, da eine Datei wie folgt zu extrahieren:wie String und Zahlen extrahieren nur mit grep/sed

miss rate 0.21 
ipc 222 
stalls n shdmem 112 

Also sagen, ich möchte nur die Daten für miss rate, die 0.21 ist zu extrahieren. Wie mache ich das mit grep oder sed? Außerdem brauche ich mehr als eine Nummer, nicht nur die nach miss rate. Das heißt, ich möchte sowohl 0.21 als auch 112 bekommen. Eine Beispielausgabe könnte so aussehen:

0.21 222 112 

Ursache Ich brauche die Daten für die spätere Handlung.

+0

Ich empfehle die Verwendung von sed anstelle von grep, wenn das für Sie funktioniert –

+0

sed ist auch akzeptabel, wenn es in diesem Fall eleganter funktioniert. – Hooloovoo

Antwort

3

Verwenden awk statt:

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

Um es mit nur grep zu tun, müssen Sie Nicht-Standard-Erweiterungen wie hier mit GNU grep PCRE (-P) mit positivem Lookbehind (? < = ..) und Spiel nur (-o):

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

können Sie verwenden:

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

oder:

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

Beide dieser Befehle werden miss rate 0.21 ausgedruckt. Wenn Sie nur die Zahl extrahieren möchten, warum nicht Perl, Sed oder Awk?

Wenn Sie diese wirklich vermeiden wollen, wird das vielleicht funktionieren?

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

Wenn Sie wirklich nur grep für diese verwenden möchten, dann können Sie versuchen:

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

Es wird zuerst die Zeile finden, die übereinstimmt, und dann nur geben die Ziffern.

Sed könnte ein bisschen besser lesbar, obwohl sein:

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

mit dem Spezial Blick um regex Trick \K mit Motor mit :

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

oder mit :

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

Added Perl tragbare Lösung =) –

+0

der \ K-Trick ist wirklich hilfreich. Ja, ich bevorzuge Grep, um dies zu tun, da ich kein Experte in awk bin und auch ein Problem mit awk ist das Feld Trennzeichen, da der Text in einem einzigen Feld mehrere und variierende #spaces wie in 'Miss Rate XX' und 'Stände insgesamt haben kann Nummer XXX ' – Hooloovoo

4

Die grep -und- cut Lösung würde wie folgt aussehen:

das 3.e Feld für jede erfolgreiche grep Nutzung zu erhalten:

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

oder das dritte Feld und den Rest Gebrauch zu bekommen:

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

Oder wenn Sie bash und „Miss-Rate“ verwenden tritt nur einmal in der Datei können Sie auch tun, nur:

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

wo ${a[2]} Ihr Ergebnis ist.

Wenn "Miss-Rate" mehr als einmal auftritt, können Sie die grep-Ausgabe lesen, die nur das liest, was Sie brauchen. (In bash)

0

Ich glaube

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

den Trick. Jedoch wird jeder Eintrag in seiner eigenen Zeile sein, wenn das in Ordnung ist. Ich bin sicher, es gibt eine Möglichkeit für sed, eine Komma oder durch Leerzeichen getrennte Liste zu erstellen, aber ich bin kein Super-Meister aller Dinge sed.

Verwandte Themen