2012-06-06 2 views
10

Ich Analyse von Protokollen enthalten Informationen wie die folgenden:Wie Sub-Expression-Wert von RegExp in awk erhalten?

y1e","email":"","money":"100","coi 

ich den Wert des Geldes holen will, habe ich ‚awk‘ wie:

grep pay action.log | awk '/"money":"([0-9]+)"/' , 

dann, wie ich die sub- bekommen Ausdruckswert in ([0-9] +)?

+0

Um zu verdeutlichen, wollen Sie den numerischen Wert nach dem ':'? – Levon

+0

Eine sed-Version wäre: 'sed -r 's | ^. * Money": "([0-9] *)". * | \ 1 |' 'oder wenn Sie keine Zeilen drucken möchten, die das tun nicht enthalten 'Geld':' sed -n -r 's | ^. * Geld ":" ([0-9] *) ". * $ | \ 1 | p'' –

+0

@Op De Cirkel Danke! Scheint 'sed' ist mächtiger! Warum hat 'awk' kein solches Design? – RoyHu

Antwort

4

Wenn Sie GNU AWK (gawk) haben:

awk '/pay/ {match($0, /"money":"([0-9]+)"/, a); print substr($0, a[1, "start"], a[1, "length"])}' action.log 

Falls nicht:

awk '/pay/ {match($0, /"money":"([0-9]+)"/); split(substr($0, RSTART, RLENGTH), a, /[":]/); print a[5]}' action.log 

Das Ergebnis ist entweder 100 . Und es gibt keine Notwendigkeit für grep.

+0

Danke. Ziemlich nah an dem, was ich erwartet habe, aber gibt es einen schlaueren Weg? – RoyHu

+0

@RoyHu: Die 1 im Array-Index bezieht sich auf die Erfassungsgruppe. Ich kenne keine andere Möglichkeit, das in Awk oder Gawk zu tun. Gawk hat eine Funktion 'gensub()', die zum * Ersetzen * des Inhalts einer Erfassungsgruppe verwendet werden kann. Sie könnten es verwenden, aber die Ausdrücke würden für die Verwendung in Ihrer Frage komplexer sein. –

+0

Danke. Und ich habe einen mit gensub: grep pay action.log | awk -F "\ n" 'm = gensub (/.* Geld ":" „. */"([0-9] +) \\ 1", "g", $ 1) {m} drucken' – RoyHu

1

Wird als Alternative angeboten, vorausgesetzt, das Datenformat bleibt gleich, sobald die Zeilen grep 'sind ed, wird dies das Geld Feld extrahieren, keinen regulären Ausdruck:

awk -v FS=\" '{print $9}' data.txt 

vorausgesetzt data.txt enthält

y1e","email":"","money":"100","coin.log 

wodurch man

100 

Ie, ist Ihr Feldtrenn gesetzt zu " und Sie ausdrucken Feld 9

+0

Danke, aber das Feld wo "Geld" Informationen enthält, kann nicht repariert werden! – RoyHu

+0

Ich denke an einen weiteren Weg: grep pay action.log | awk -F "\ n" 'm = gensub (/.* money ":" ([0-9] +) ". * /," \\ 1 "," g ", $ 1) {print m} ' – RoyHu

0

Wenn Siehabenkommen an verschiedenen Stellen dann vielleicht wäre es keine gute Idee, den Positionsparameter fest zu codieren.

Sie können so etwas wie dies versuchen -

$ awk -v FS=[,:\"] '{ for (i=1;i<=NF;i++) if($i~/money/) print $(i+3)}' inputfile 
+0

Danke das funktioniert.aber ich möchte wissen, wie awk den Wert der Gruppe 1 holen. – RoyHu

0
grep pay action.log | awk -F "\n" 'm=gensub(/.*money":"([0-9]+)".*/, "\\1", "g", $1) {print m}' 
+1

Sie sollten die' grep' Refactoring aus Beachten Sie, dass 'grep‚foo‘Datei | awk‚{. bar} ''ist grundsätzlich immer besser als' awk '/ foo/{bar}' Datei 'geschrieben. – tripleee