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

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.)


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


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.


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 }'

0

Sollte das nicht funktionieren?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.