awk
1. Fonctionnement
awk est un filtre.
Il interprête un script de la forme :
condition { action ; action ; action ; ... }
condition { action ; action ; action ; ... }
condition { action ; action ; action ; ... }
...
Pour chacune des lignes de texte du flux vérifiant la condition, les actions associées sont exécutées.
2. Découpage automatique de la ligne courante en champs
Les variables $1, $2 … contiennent le champ n°1, n°2 … de la ligne courante.
$0 correspond à la ligne complète.
who | awk '{print $1,$4}'
Le séparateur qui sert au découpage peut être spécifié par
l’option -F :
awk -F ":" '{ $2="" ; print $0 }' /etc/passwd
3. Variables
FS |
Field Separator |
separateur de champs en entrée |
OFS |
Output Field Separator |
separateur de champs en sortie |
NF |
Number of Fields |
nombre de champs de la ligne courante |
NR |
Number Record |
n° de la ligne courante |
RS |
Record Separator |
separateur de ligne en entrée |
ORS |
Output Record Separator |
separateur de ligne en sortie |
$ man sed | awk 'NR>2 && NR<10 { print }' # print est équivalent à print $0
$ awk '{print NR ":", $0}' /etc/passwd
La variable NF contient le nombre de champs de la ligne courante, donc $NF correspond à la valeur du dernier champ :
awk '{print NF,$NF}' /etc/mime.types
4. BEGIN et END
Il existe 2 conditions particulières :
-
BEGINqui est vraie avant l’arrivée de la première ligne, fausse ensuite -
ENDqui est vraie après l’envoi de la dernière ligne, fausse avant.
fawk 'END {print NR}' /etc/mime.types
awk 'BEGIN {FS=":";OFS=" -> "}
{print $5,$1}
' /etc/passwd
$ ls -l | awk 'BEGIN { s=0 }
{ s=s+$5 }
END { print s }'
5. Conditions
awk -F= '/^[^ ]*=/ {print $1}' /etc/crontab
awk 'length($0)<75 {print}' /etc/services
awk '/^#/ {next}
$4!="#" {next}
{$1=$2=$3=$4="";print}
' /etc/protocols
awk 'BEGIN {OFS=" => "}
/^#/ {next}
/^\s*$/ {next}
{print $2,$3}
' /etc/fstab
$ man awk| awk '/^SYNOPSIS$/,/^DESCRIPTION$/ { print}'
6. Exemples plus costauds
awk 'BEGIN { print "Verification des UID et GID dans le fichier /etc/passwd";
FS=":"}
$3 !~ /^[0-9][0-9]*$/ {print "UID erreur ligne "NR" :\n"$0 }
$4 !~ /^[0-9][0-9]*$/ {print "GID erreur ligne "NR" :\n"$0 }
END { print "Fin" }
' /etc/passwd
awk 'BEGIN { print "Verification du fichier /etc/passwd pour ...";
print "- les utilisateurs avec UID = 0 " ;
print "- les utilisateurs avec UID >= 60000" ;
FS=":"}
$3 == 0 { print "UID 0 ligne "NR" :\n"$0 }
$3 >= 60000 { print "UID >= 60000 ligne "NR" :\n"$0 }
END { print "Fin" }
' /etc/passwd
Créer un nouveau fichier de mot de passe /tmp/passwd.new
en remplacant le shell /bin/bash par /bin/zsh :
awk 'BEGIN { FS=":" ;
OFS=":"}
$NF != "/bin/bash" { print }
$NF == "/bin/bash" { $NF = "/bin/zsh" ;
print }
' /etc/passwd > /tmp/passwd.new