Valeurs séparées par des tabulations dans awk


90

Comment sélectionner la première colonne de la chaîne séparée par TAB?

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

Ce qui précède renverra la ligne entière et pas seulement "LOAD_SETTLED" comme prévu.

Mise à jour:

J'ai besoin de changer la troisième colonne dans les valeurs séparées par tabulation. Ce qui suit ne fonctionne pas.

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

Cela fonctionne cependant comme prévu si le séparateur est une virgule au lieu d'une tabulation.

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} '# c'est ce que je cherchais. Ma recherche Google est-elle correcte? :)
— shantanuo

3
Grâce à ce commentaire, j'ai découvert: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txtpour imprimer les valeurs délimitées par des tabulations des trois premières colonnes.
— Wok

6
Ou peut-être simplementawk 'BEGIN {OFS="\t"}; {print $1,$2,$3}'
— Josiah Yoder

3
Le support awk GNU et BSD -vpour la définition des variables. C'est moche à utiliser BEGIN {FS="\t"}dans un programme en ligne , et toute contribution open source que vous essayez de faire comme celle-ci est susceptible d'être contestée. Ne faites cela que si vous écrivez un fichier programme . En outre, il est déconseillé d'utiliser à la -Fplace de -v FS=car ce dernier indique clairement que seul FSest défini et non OFS. La confusion sur ce dernier point est ce qui a causé ce message en premier lieu. C'est pourquoi le «bon style» est important.
— Bruno Bronosky

1
S'il vous plaît, personne, jamais, ne devrait faire ce que @Wok a démontré. Vous n'énumérez pas les séparateurs de champs [Entrée] dans votre sortie. Vous spécifiez un séparateur de champ de sortie via la OFSvariable.
— Bruno Bronosky

Réponses:


141

Vous devez définir la OFSvariable (séparateur de champ de sortie) comme un onglet:

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

(assurez-vous de citer la $linevariable dans l'instruction echo)


6
Quel est le but du $ dans $ '\ t'?
— Amr Mostafa

10
Répondre à ma propre question du Guide de script avancé Bash : La construction d'extension de chaîne entre guillemets $ '...' est un mécanisme qui utilise des valeurs octales ou hexadécimales échappées ..., par exemple, quote = $ '\ 042'.
— Amr Mostafa

5
@AmrMostafa, trop mauvais ce guide a une explication trompeuse conduisant à penser que vous ne l' $en $'\t'est pas nécessaire. Le wiki de Greg est meilleur: "Parmi ceux-ci, $'...'est le plus courant, et agit comme des guillemets simples sauf que les combinaisons échappées par une barre oblique inverse sont développées comme spécifié par la norme ANSI C".
— Cristian Ciupitu

9
Avec le recul, le $'\t'n'est pas nécessaire. awk comprend que la chaîne "\t"est un caractère de tabulation
— glenn jackman

5
Contributeurs Open Source, je vous en prie, veuillez ne pas soumettre de choses comme awk -F $'\t' 'BEGIN {OFS = FS} …'. Cela devrait être awk -v FS='\t' -v OFS='\t' '…'. Cela peut sembler pédant, mais être incohérent augmente les chances qu'un contributeur ultérieur introduise un bogue parce qu'il comprend mal votre code.
— Bruno Bronosky

21

Assurez-vous que ce sont vraiment des onglets! Dans bash, vous pouvez insérer un onglet en utilisantC-v TAB

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


9

J'utilise les variables FSet OFSpour manipuler les fichiers de zone BIND délimités par des tabulations. Voici l'un de mes scripts https://gist.github.com/RichardBronosky/abe1652c2d5c78c35b92ad02bdf0d0af#file-dns_update-sh-L36-L39

La viande de celui-ci est:

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

C'est une manière claire et facile à lire de faire cela.


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

Cela ne devrait-il pas fonctionner?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.