User Tools

Site Tools


informatique:linux:awk

This is an old revision of the document!


search?q=langage%20programmation&btnI=lucky

awk

C'est un langage de manipulation de chaînes de caractères d'un fichier ou d'un flux en entrée.

Les différentes commandes que l'on peut passer sont de la forme motif { action }. awk traite séquentiellement le flux de caractères (fichier en paramètre ou flux en entrée) par ligne (enregistrement) et colonne (champ) ; on peut récupérer les colonnes avec les variables $1, $2, .., $10 ,$NF (dernière colonne) et $0 qui correspond à la ligne complète. Les champs peuvent être spécifiés par des expressions, comme $(NF-1) pour l'avant dernier champs.

Le motif

  • une expression régulière : “/regexp/” ; “expression ~ /regexp/” ou sa négation “expression !~ /regexp/”

Pour utiliser une variable bash comme regexp avec awk, on peut procéder ainsi :

awk '$1 ~ /^'$VAR'/ {print}'
  • BEGIN ou END (BEGIN permet de faire des actions avant le traitement du fichier ; END permet de les faire à la fin du traitement)
  • une comparaison (<, >, ⇒, !=, …)
  • une combinaison des 3 séparés d'un opérateur booléen (|| ou &&)

Les options

  • -f <fichier> la commande s'applique à un fichier
  • -F “<séparateur>” spécifie le séparateur de champs (“ ” (espace) par défaut). NB : on peut spécifier plusieurs séparateurs en les séparant par “|” :
echo "toto;tata-titi" | awk -F":|-" '{print $1" "$2" "$3}'
 toto tata titi
  • -v var=“val” : permet d'affecter une valeur val à une variable var avant la partie BEGIN
HOST=toto ; echo titi | awk -v h=$HOST '{print "h="h}'
 h=toto

Les variables prédéfinies

<variable> <desc> <valeur par défaut>

  • ARGC Nombre d'arguments de la ligne de commande
  • ARGV tableau des arguments de la ligne de commnde
  • FILENAME nom du fichier sur lequel on applique les commandes
  • FNR Nombre d'enregistrements du fichier
  • FS separateur de champs en entrée
  • NF nombre de champs de l'enregistrement courant
  • NR nombre d'enregistrements deja lu
  • OFMT format de sortie des nombres
  • OFS separateur de champs pour la sortie
  • ORS separateur d'enregistrement pour la sortie
  • RLENGTH longueur de la chaine trouvée
  • RS separateur d'enregistrement en entrée
  • RSTART debut de la chaine trouvée
  • SUBSEP separateur de subscript

Les fonctions

Les paramètres sont soit des chaines de caractère (s et t), soit des regexp ® soit des entiers (i et n).

  • gsub(r,s,t) : sur la chaine t, remplace toutes les occurrence de r par s
  • index(s,t) : retourne la position la plus à gauche de la chaine t dans la chaine s
  • length(s) : retourne la longueur de la chaine s
  • match(s,r) : retourne l'index ou s correspond à r et positionne RSTART et RLENTH
  • split(s,a,fs) : split s dans le tableau a sur fs, retourne le nombre de champs
  • sprintf(fmt,liste expressions) : retourne la liste des expressions formatée suivant fmt
  • sub(r,s,t) : comme gsub, mais remplace uniquement la première occurrence
  • substr(s,i,n) : retourne la sous chaine de s commençant en i et de taille n

Exemples

  • imprime chaque ligne du fichier /etc/passwd après avoir effacé le deuxième champs
awk -F ":" '{ $2 = "" ; print $0 }' /etc/passwd
  • imprime le nombre total de lignes du fichiers
awk 'END {print NR}' /etc/passwd
  • lire la 3ème ligne d'un fichier :
awk '{if (NR==3) print}' <fichier>
  • imprime le dernier champs de chaque ligne
awk '{print $NF}' /etc/passwd
  • imprime le login et le temps de connexion.
who | awk '{print $1,$5}'
  • imprime les lignes de plus de 75 caractères. (print équivaut à print $0)
awk 'length($0)>75 {print}' /etc/passwd
  • tests sur le fichier /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
  • supprimer le suffixe du domaine d'un nom de machine :
echo "toto.domaine.fr est un nom trop long !" | awk 'gsub(/\..*$/,"",$1) {print "machine="$1}'
informatique/linux/awk.1273051980.txt.gz · Last modified: 2013/10/14 22:54 (external edit)