Wie verwende ich ":" als awk-Feldtrennzeichen?

243

Gegeben folgenden Befehl:

echo "1: " | awk '/1/ -F ":" {print $1}'

Warum gibt awk aus:

1: 
user173446
quelle

Antworten:

382

"-F" ist ein Befehlszeilenargument ohne awk-Syntax. Versuchen Sie:

 echo "1: " | awk -F  ":" '/1/ {print $1}'
Jürgen Hötzel
quelle
42
Die Frage von Ignorant hier: Der Teil / 1 / soll awk anweisen, nur Zeilen (oder genauer gesagt Datensätze) zu verarbeiten, die die Nummer 1 enthalten, oder?
Rantsh
3
Die Syntax von @rantsh Awk sieht aus wie (pattern){action}. Wenn pattern(meistens eine bedingte Aussage) wahr ist , actionwird ausgeführt. Wenn patternnicht verfügbar, trueist impliziert. Hier patternist /1/der Status, 1mit dem der Regex im aktuellen Datensatz$0
übereinstimmt
62

Wenn Sie es programmgesteuert ausführen möchten, können Sie die FSVariable verwenden:

echo "1: " | awk 'BEGIN { FS=":" } /1/ { print $1 }'

Beachten Sie, dass wenn Sie es in der Hauptschleife anstatt in der Schleife ändern BEGIN, es für die nächste eingelesene Zeile wirksam wird, da die aktuelle Zeile bereits geteilt wurde.

Bis auf weiteres angehalten.
quelle
35

Sie haben mehrere Möglichkeiten, :als Trennzeichen festzulegen:

awk -F: '{print $1}'

awk -v FS=: '{print $1}'

awk '{print $1}' FS=:

awk 'BEGIN{FS=":"} {print $1}'

Alle von ihnen sind gleichwertig und werden 1für eine Beispieleingabe "1: 2: 3" zurückgegeben:

$ awk -F: '{print $1}' <<< "1:2:3"
1
$ awk -v FS=: '{print $1}' <<< "1:2:3"
1
$ awk '{print $1}' FS=: <<< "1:2:3"
1
$ awk 'BEGIN{FS=":"} {print $1}' <<< "1:2:3"
1
fedorqui 'SO hör auf zu schaden'
quelle
Welches ist der bevorzugte Weg? Ich gehe davon aus, dass das letzte Beispiel mit der BEGINAnweisung am korrektesten ist (in Übereinstimmung mit der Gesamtsyntax awk).
1
@ Randomware alle von ihnen sind in Ordnung. Ich neige dazu, zu verwenden, BEGINwenn ich eine Datei verwende, um das Ganze zu speichern, während es -Fbei Einzeilern nützlich ist.
fedorqui 'SO hör auf,'
1
Es muss gesagt werden, dass es subtile Unterschiede zwischen dem dritten Fall und allen anderen gibt. Beispiel: awk 'BEGIN{print split("foo:bar",a)}' FS=":" fileundawk 'BEGIN{FS=":"; print split("foo:bar",a)}' file
kvantour
@kvantour guter Punkt. Ich habe gerade danach gefragt, warum das Feldtrennzeichen anders berücksichtigt wird, wenn es vor oder nach dem Ausdruck festgelegt wird. .
Fedorqui 'SO hör auf zu schaden'
12

-Fist ein Argument für awksich:

$echo "1: " | awk -F":" '/1/ {print $1}'
1
danben
quelle
2
Keine Notwendigkeit, Doppelpunkt zu zitieren.
Ceving
6

Sie können auch einen regulären Ausdruck als Feldtrennzeichen verwenden. Im Folgenden wird "Balken" gedruckt, indem ein regulärer Ausdruck verwendet wird, um die Zahl "10" als Trennzeichen festzulegen.

echo "foo 10 bar" | awk -F'[0-9][0-9]' '{print $2}'
Zlemini
quelle
4

Keine Notwendigkeit, so viel zu schreiben. Fügen Sie einfach Ihr gewünschtes Feldtrennzeichen mit der Option -F in den Befehl awk ein und die Spaltennummer, die Sie drucken möchten, getrennt nach Ihrem genannten Feldtrennzeichen.

echo "1: " | awk -F: '{print $1}'    
1

echo "1#2" | awk -F# '{print $1}'  
1
Bhavuk Taneja
quelle
4

AWK arbeitet als Text - Interpreter , die linewise für das gesamte Dokument geht und das geht feld für jede Zeile so 1, $ 2 $ .. $ n sind Verweise auf die Felder jeder Zeile ($ 1 das erste Feld, $ 2 ist das zweite Feld und so weiter ...). Sie können ein Feldtrennzeichen definieren, indem Sie den Schalter "-F" unter der Befehlszeile oder in zwei Klammern mit "FS = ..." verwenden. Betrachten Sie nun die Antwort von "JUERGEN":

echo "1: " | awk -F  ":" '/1/ {print $1}'

Über den Feldgrenzen werden durch ":" gesetzt, so dass wir zwei Felder $ 1 haben, die "1" sind, und $ 2, die der leere Raum ist. Danach folgt der reguläre Ausdruck "/ 1 /", der den Filter anweist, nur das erste Feld auszugeben wenn der Dolmetscher auf eine Zeile stößt, die einen solchen Ausdruck enthält (ich meine 1); Die Ausgabe des Befehls "echo" ist eine Zeile, die "1" enthält, damit der Filter funktioniert ...

Im folgenden Beispiel:

echo "1: " | awk '/1/ -F ":" {print $1}'

Die Syntax ist chaotisch und der Interpreter hat den Teil F ":" ignoriert. und wechselt zum Standardfeldteiler, der der leere Raum ist, wodurch "1:" als erstes Feld ausgegeben wird und es kein zweites Feld gibt!

Die Antwort von JUERGEN enthält die gute Syntax ...

jihed gasmi
quelle
2

Oder Sie können verwenden:

echo "1: " | awk  '/1/{print $1-":"}' 

Das ist wirklich eine lustige Gleichung.

Vonton
quelle
1
was tut /1/bedeuten?
Finde ein Muster. In diesem Fall "1"
José Dias