Tabulatorgetrennte Werte in awk

88

Wie wähle ich die erste Spalte aus der durch TAB getrennten Zeichenfolge aus?

# echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F'\t' '{print $1}'

Das Obige gibt die gesamte Zeile zurück und nicht nur "LOAD_SETTLED" wie erwartet.

Aktualisieren:

Ich muss die dritte Spalte in den tabulatorgetrennten Werten ändern. Folgendes funktioniert nicht.

echo $line | awk 'BEGIN { -v var="$mycol_new" FS = "[ \t]+" } ; { print $1 $2 var $4 $5 $6 $7 $8 $9 }' >> /pdump/temp.txt

Dies funktioniert jedoch wie erwartet, wenn das Trennzeichen ein Komma anstelle eines Tabulators ist.

echo $line | awk -v var="$mycol_new" -F'\t' '{print $1 "," $2 "," var "," $4 "," $5 "," $6 "," $7 "," $8 "," $9 "}' >> /pdump/temp.txt
Shantanuo
quelle
4
awk 'BEGIN {FS = "[\ t] +"}; {print $ 1} '# das ist was ich gesucht habe. Ist meine Google-Suche korrekt? :)
Shantanuo
2
Dank dieses Kommentars habe ich festgestellt: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txtTabulatorgetrennte Werte der ersten drei Spalten zu drucken.
Wok
6
Oder vielleicht einfachawk 'BEGIN {OFS="\t"}; {print $1,$2,$3}'
Josiah Yoder
3
Sowohl GNU als auch BSD awk unterstützen das -vEinstellen von Variablen. Die Verwendung BEGIN {FS="\t"}in einem Inline-Programm ist hässlich , und jeder Open-Source-Beitrag, den Sie auf diese Weise leisten möchten, wird wahrscheinlich beanstandet. Tun Sie das nur, wenn Sie eine Programmdatei schreiben . Es wird auch davon abgeraten, -Fstatt zu verwenden, -v FS=da letzteres klarstellt, dass nur FSgesetzt wird und nicht OFS. Die Verwirrung über diesen letzten Punkt hat diesen Beitrag überhaupt erst verursacht. Deshalb ist "guter Stil" wichtig.
Bruno Bronosky
1
Bitte, niemand sollte jemals das tun, was @Wok demonstriert hat. Sie führen in Ihrer Ausgabe keine [Eingabe] -Feldtrennzeichen auf. Über die OFSVariable geben Sie ein Ausgabefeldtrennzeichen an .
Bruno Bronosky

Antworten:

136

Sie müssen die OFSVariable (Ausgabefeldtrennzeichen) als Registerkarte festlegen :

echo "$line" | 
awk -v var="$mycol_new" -F $'\t' 'BEGIN {OFS = FS} {$3 = var; print}'

(Stellen Sie sicher, dass Sie die $lineVariable in der Echo-Anweisung angeben.)

Glenn Jackman
quelle
6
Was ist der Zweck des $ in $ '\ t'?
Amr Mostafa
10
Beantwortung meiner eigenen Frage aus dem Advanced Bash Scripting Guide : Das in $ '...' zitierte String-Erweiterungskonstrukt ist ein Mechanismus, der maskierte Oktal- oder Hex-Werte verwendet ... z. B. quote = $ '\ 042'.
Amr Mostafa
4
@AmrMostafa, schade , dass Führung eine irreführende Erklärung hat man was zu denken , dass Sie nicht die $in $'\t'nicht benötigt wird . Gregs Wiki ist besser: "Von diesen $'...'ist es das häufigste und verhält sich wie einfache Anführungszeichen, mit der Ausnahme, dass Kombinationen mit Backslash-Escapezeichen gemäß dem ANSI C-Standard erweitert werden."
Cristian Ciupitu
9
Im Nachhinein ist das $'\t'nicht nötig. awk versteht die Zeichenfolge "\t"als Tabulatorzeichen
Glenn Jackman
5
Open Source Contributors, ich bitte Sie, bitte reichen Sie keine Sachen wie ein awk -F $'\t' 'BEGIN {OFS = FS} …'. Das sollte sein awk -v FS='\t' -v OFS='\t' '…'. Es mag pedantisch erscheinen, aber inkonsistent zu sein erhöht die Wahrscheinlichkeit, dass ein späterer Mitwirkender einen Fehler einführt, weil er Ihren Code falsch versteht.
Bruno Bronosky
21

Stellen Sie sicher, dass sie wirklich Tabs sind! In bash können Sie mit ein Tab einfügenC-v TAB

$ echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F$'\t' '{print $1}'
LOAD_SETTLED
Mahmoud Abdelkader
quelle
8

Ich verwende die Variablen FSund OFS, um BIND-Zonendateien zu bearbeiten, die durch Tabulatoren getrennt sind. Hier ist eines meiner Skripte https://gist.github.com/RichardBronosky/abe1652c2d5c78c35b92ad02bdf0d0af#file-dns_update-sh-L36-L39

Das Fleisch davon ist:

awk -v FS='\t' -v OFS='\t' \
    -v record_type=$record_type \
    -v hostname=$hostname \
    -v ip_address=$ip_address '
$1==hostname && $3==record_type {$4=ip_address}
{print}
' $zone_file > $temp

Dies ist eine saubere und leicht zu lesende Methode, um dies zu tun.

Bruno Bronosky
quelle
5
echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -v var="test" 'BEGIN { FS = "[ \t]+" } ; { print $1 "\t" var "\t" $3 }'
Shantanuo
quelle
0

Sollte das nicht funktionieren?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
asadz
quelle