Valori separati da tabulazione in awk


90

Come faccio a selezionare la prima colonna dalla stringa separata da TAB?

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

Quanto sopra restituirà l'intera riga e non solo "LOAD_SETTLED" come previsto.

Aggiornare:

Ho bisogno di cambiare la terza colonna nei valori separati da tabulazione. Quanto segue non funziona.

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

Ciò tuttavia funziona come previsto se il separatore è una virgola anziché una tabulazione.

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} '# questo è quello che stavo cercando. La mia ricerca su Google è corretta? :)
shantanuo

3
Grazie a questo commento, ho scoperto: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txtstampare i valori delimitati da tabulazioni delle prime tre colonne.
Wok

6
O forse semplicementeawk 'BEGIN {OFS="\t"}; {print $1,$2,$3}'
Josiah Yoder

3
Sia GNU che BSD awk supportano l' -vimpostazione delle variabili. È brutto da usare BEGIN {FS="\t"}all'interno di un programma inline e qualsiasi contributo open source che si tenta di fornire in questo modo sarà probabilmente respinto. Fallo solo se stai scrivendo un file di programma . Inoltre, è sconsigliato utilizzare -Finvece di -v FS=perché quest'ultimo chiarisce che FSviene impostato solo e non OFS. La confusione su quest'ultimo punto è ciò che ha causato questo post in primo luogo. Ecco perché il "buon stile" è importante.
Bruno Bronosky

1
Per favore, nessuno, mai, dovrebbe fare quello che ha dimostrato @Wok. Non enumerare i separatori di campo [Input] nell'output. Specificare un separatore del campo di output tramite la OFSvariabile.
Bruno Bronosky

Risposte:


141

È necessario impostare la OFSvariabile (separatore del campo di output) come tab:

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

(assicurati di citare la $linevariabile nell'istruzione echo)


6
Qual è lo scopo di $ in $ '\ t'?
Amr Mostafa

10
Rispondendo alla mia domanda dalla Guida avanzata allo scripting di Bash : Il costrutto di espansione di stringa $ '...' quotato è un meccanismo che utilizza valori ottali o esadecimali con escape ..., ad esempio, quote = $ '\ 042'.
Amr Mostafa

5
@AmrMostafa, peccato che guida ha una spiegazione fuorviante che porta a pensare che tu non l' $in $'\t'non è necessario. Il wiki di Greg è migliore: "Di questi, $'...'è il più comune e si comporta proprio come le virgolette singole tranne che le combinazioni con escape backslash vengono espanse come specificato dallo standard ANSI C".
Cristian Ciupitu

9
Col senno di poi, $'\t'non è necessario. awk capisce che la stringa "\t"è un carattere di tabulazione
glenn jackman

5
Collaboratori Open Source, vi prego, per favore non inviate cose come awk -F $'\t' 'BEGIN {OFS = FS} …'. Dovrebbe essere awk -v FS='\t' -v OFS='\t' '…'. Può sembrare pedante, ma essere incoerenti aumenta le possibilità che un contributore successivo introduca un bug perché fraintende il tuo codice.
Bruno Bronosky

21

Assicurati che siano davvero schede! In bash, puoi inserire una tabulazione usandoC-v TAB

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


9

Uso le variabili FSe OFSper manipolare i file di zona BIND che sono delimitati da tabulazioni. Ecco uno dei miei script https://gist.github.com/RichardBronosky/abe1652c2d5c78c35b92ad02bdf0d0af#file-dns_update-sh-L36-L39

La sua carne è:

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

Questo è un modo pulito e di facile lettura per farlo.


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

Questo non dovrebbe funzionare?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.