it-swarm.com.de

Wie passt man ein Muster an, das in einer Variablen in awk angegeben ist?

Ich möchte einen Teilstring extrahieren, in dem ein bestimmtes Muster aus der durch Pfeifen getrennten Datei vorhanden ist.

awk -F ":" '/REWARD REQ. SERVER HEADERS/{print $1, $2, $3, $4}' sample_profile.txt

Hier 'REWARD REQ. SERVER HEADERS 'ist ein Muster, das in der Datei gesucht werden soll und die ersten 4 Teile in einer durch Doppelpunkt getrennten Zeile ausgeben soll.

Nun möchte ich die bash-Variable senden, um als Muster zu fungieren. also habe ich den folgenden Befehl verwendet, aber es funktioniert nicht.

awk -v pat="$pattern" -F ":" '/pat/{print $1, $2 , $3, $4 } sample_profile.txt

Wie kann ich -v und -F in einem einzigen awk-Befehl verwenden?

13

Das Problem hat hier nicht mit -F zu tun.

Das Problem ist die Verwendung von /pat/, wenn pat eine Variable sein soll. Wenn Sie /pat/ sagen, versteht awk es als wörtliches "pat", also versucht es, die Zeilen mit der Zeichenfolge "pat" abzugleichen.

Wenn Sie das Muster über eine Variable bereitstellen möchten, müssen Sie ~ wie folgt verwenden:

 awk -v pat="$pattern" '$0 ~ pat'

Alles in allem sollte Ihr Code sein:

awk -v pat="$pattern" -F ":" '$0~pat{print $1, $2, $3, $4 }' file
#                             ^^^^^^

Siehe ein Beispiel:

Gegeben diese Datei:

$ cat file
hello
this is a var
hello bye

Suchen wir nach Zeilen, die "Hallo" enthalten:

$ awk '/hello/' file
hello
hello bye

Versuchen wir nun, nach "pat" zu suchen, das in einer Variablen enthalten ist, wie Sie es getan haben:

$ awk -v pat="hello" '/pat/' file
$                                    # NO MATCHES!

Verwenden wir nun den Ausdruck $0 ~ pat:

$ awk -v pat="hello" '$0~pat' file
hello                                 # WE MATCH!
hello bye

Natürlich können Sie solche Ausdrücke verwenden, um nur ein Feld zu finden und awk -v pat="$pattern" '$2 ~ pat' file usw. zu sagen.

Von GNU Awk Benutzerhandbuch → 3.1 So verwenden Sie reguläre Ausdrücke :

Wenn ein Regex in Schrägstriche eingeschlossen ist, wie zum Beispiel/foo /, nennen wir es eine Regex-Konstante, ähnlich wie 5.27 eine numerische Konstante und "foo" eine String-Konstante.

And GNU Awk Benutzerhandbuch → 3.6 Verwenden von Dynamic Regexps :

Die rechte Seite eines '~' oder '! ~' Operators muss kein Regex sein konstant (d. h. eine Zeichenfolge zwischen Schrägstrichen). Es kann beliebig sein Ausdruck. Der Ausdruck wird ausgewertet und in eine Zeichenfolge umgewandelt, wenn notwendig; Der Inhalt der Zeichenfolge wird dann als regulärer Ausdruck verwendet. EIN Der auf diese Weise berechnete reguläre Ausdruck wird als dynamischer regulärer Ausdruck oder berechneter Wert bezeichnet. regulärer Ausdruck:

BEGIN { digits_regexp = "[[:digit:]]+" }
$0 ~ digits_regexp    { print }

Dadurch wird für digits_regexp ein regulärer Ausdruck gesetzt, der eine oder mehrere Ziffern beschreibt und testet, ob der Eingabedatensatz mit diesem regulären Ausdruck übereinstimmt.

26
fedorqui
awk -v pat="$pattern" -F":" '$0 ~ pat { print $1, $2, $3, $4 }' sample_profile.txt

Sie können die Variable nicht in der Regex-//-Notation verwenden (sie kann nicht von der Suche nach pat unterschieden werden); Sie müssen angeben, dass die Variable mit dem Operator ~ (übereinstimmend) eine reguläre Ausdrücke ist.

4

Dies ist eine Art Hack, aber es macht die Sache für mich ein bisschen einfacher.

cmd="awk '/$pattern/'"
eval $cmd

wenn Sie den String zuerst zu einem String machen, können Sie ihn über die Grenzen von awk hinaus bearbeiten

0
Ryan Donahoe