User Tools

Site Tools


informatique:linux:awk

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
informatique:linux:awk [2011/01/05 16:26] – [Les variables prédéfinies] pteuinformatique:linux:awk [2019/06/06 09:21] – fonction trim pteu
Line 22: Line 22:
 ====Les options==== ====Les options====
  
-  * ''-f <fichier>'' la commande s'applique à un fichier+  * ''-f <fichier>'' précise un fichier de script awk 
 +<code bash> 
 +vi test.awk 
 +BEGIN{FS=";"; OFS=" : "} 
 +$0 ~ "test" {print $0} 
 +:x 
 + 
 +awk -f test.awk fichier.txt 
 + ceci est un test 
 +</code>
   * ''-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 "|" :   * ''-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 "|" :
-<code>+<code bash>
 echo "toto;tata-titi" | awk -F":|-" '{print $1" "$2" "$3}' echo "toto;tata-titi" | awk -F":|-" '{print $1" "$2" "$3}'
  toto tata titi  toto tata titi
 </code> </code>
   * ''-v var="val"'' : permet d'affecter une valeur //val// à une variable //var// avant la partie BEGIN   * ''-v var="val"'' : permet d'affecter une valeur //val// à une variable //var// avant la partie BEGIN
-<code>+<code bash>
 HOST=toto ; echo titi | awk -v h=$HOST '{print "h="h}' HOST=toto ; echo titi | awk -v h=$HOST '{print "h="h}'
  h=toto  h=toto
 +</code>
 +
 +Autre façon de passer des variables dans un fichier de script :
 +<code bash>
 +vi test.awk
 +BEGIN{FS=";"; OFS=" : "}
 +$0 ~ rechch {print $0}
 +:x
 +
 +awk -f test.awk rechch=test fichier.txt
 + ceci est un test
 </code> </code>
  
Line 53: Line 73:
 | SUBSEP   | séparateur de subscript || | SUBSEP   | séparateur de subscript ||
  
-====Les fonctions====+====Les fonctions texte====
  
-Les paramètres sont soit des chaines de caractère (s et t), soit des regexp (r) soit des entiers (i et n).+Les paramètres sont soit des chaines de caractères (s et t), soit des regexp (r) soit des entiers (i et n).
   * ''gsub(r,s,t)'' : sur la chaine t, remplace toutes les occurrence de r par s   * ''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   * ''index(s,t)'' : retourne la position la plus à gauche de la chaine t dans la chaine s
Line 64: Line 84:
   * ''sub(r,s,t)'' : comme gsub, mais remplace uniquement la première occurrence   * ''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   * ''substr(s,i,n)'' : retourne la sous chaine de s commençant en i et de taille n
 +  * ''tolower(s)'' : passer la chaîne en minuscules
 +  * ''toupper(s)'' : passer la chaîne en majuscules
 +
 +===Le cas printf===
 +
 +**printf** et ses dérivées sont des fonctions d'affichage de texte qui permettent de formater la sortie (pour un résultat bien léché comme on aime). Voici quelques cas d'utilisation commentés :
 +<code bash>
 +# afficher les logins et description des utilisateurs locaux qui utilisent le shell /bin/bash
 +# en alignant les logins à droite et sur 20 caractères
 +awk -F: '$7 ~ /\/bin\/bash/ {printf "%-20s %s\n", $1, $5}' /etc/passwd
 +root                 root
 +dude                 a dude
 +robert               le gros robert
 +
 +# puisque l'affichage est par colonne, on va afficher les noms pour être plus parlant
 +# on utilise l'instruction BEGIN qui, comme on l'a vu, ne s'exécute qu'une fois en début de script
 +awk -F: 'BEGIN {printf "%-20s %s\n", "login:","description:"} $7 ~ /\/bin\/bash/ {printf "%-20s %s\n", $1, $5}' /etc/passwd
 +login:               description:
 +root                 root
 +dude                 a dude
 +robert               le gros robert
 +
 +# on peut même définir un format d'affichage pour ne pas avoir a le retaper à chaque printf :
 +awk -F: 'BEGIN {format = "%-20s %s\n"; printf format, "login:","description:"; printf format, "---","---"} $7 ~ /\/bin\/bash/ {printf format, $1, $5}' /etc/passwd
 +login:               description:
 +---                  ---
 +root                 root
 +dude                 a dude
 +robert               le gros robert
 +
 +# la même commande, en plus lisible :
 +awk -F: 'BEGIN {format = "%-10s %s\n"
 + printf format, "login:","description:"
 + printf format, "---","---"}
 + $7 ~ /\/bin\/bash/ {printf format, $1, $5}' /etc/passwd
 +</code>
 +
 +====Les fonctions mathématiques====
 +
 +cos(x), exp(x), int(x), log(x), sin(x), sqrt(x), atan2(x,y), rand(x), srand(x)
  
 ====Exemples==== ====Exemples====
  
   * imprime chaque ligne du fichier /etc/passwd après avoir effacé le deuxième champs   * imprime chaque ligne du fichier /etc/passwd après avoir effacé le deuxième champs
-<code>+<code bash>
 awk -F ":" '{ $2 = "" ; print $0 }' /etc/passwd awk -F ":" '{ $2 = "" ; print $0 }' /etc/passwd
 </code> </code>
  
   * imprime le nombre total de lignes du fichiers   * imprime le nombre total de lignes du fichiers
-<code>+<code bash>
 awk 'END {print NR}' /etc/passwd awk 'END {print NR}' /etc/passwd
 </code> </code>
  
   * lire la 3ème ligne d'un fichier :   * lire la 3ème ligne d'un fichier :
-<code>+<code bash>
 awk '{if (NR==3) print}' <fichier> awk '{if (NR==3) print}' <fichier>
 </code> </code>
  
   * imprime le dernier champs de chaque ligne   * imprime le dernier champs de chaque ligne
-<code>+<code bash>
 awk '{print $NF}' /etc/passwd awk '{print $NF}' /etc/passwd
 </code> </code>
  
   * imprime le login et le temps de connexion.   * imprime le login et le temps de connexion.
-<code>+<code bash>
 who | awk '{print $1,$5}' who | awk '{print $1,$5}'
 </code> </code>
  
   * imprime les lignes de plus de 75 caractères. (''print'' équivaut à ''print $0'')   * imprime les lignes de plus de 75 caractères. (''print'' équivaut à ''print $0'')
-<code>+<code bash>
 awk 'length($0)>75 {print}' /etc/passwd awk 'length($0)>75 {print}' /etc/passwd
 </code> </code>
  
   * tests sur le fichier /etc/passwd :   * tests sur le fichier /etc/passwd :
-<code>+<code bash>
 awk 'BEGIN { print "Verification du fichier /etc/passwd pour ..."; awk 'BEGIN { print "Verification du fichier /etc/passwd pour ...";
             print "- les utilisateurs avec UID = 0 " ;             print "- les utilisateurs avec UID = 0 " ;
Line 110: Line 170:
  
   * supprimer le suffixe du domaine d'un nom de machine :   * supprimer le suffixe du domaine d'un nom de machine :
-<code>+<code bash>
 echo "toto.domaine.fr est un nom trop long !" | awk 'gsub(/\..*$/,"",$1) {print "machine="$1}' echo "toto.domaine.fr est un nom trop long !" | awk 'gsub(/\..*$/,"",$1) {print "machine="$1}'
 </code> </code>
  
 +  * afficher les blocs de texte du fichier FIC.txt compris entre les balises BEGIN et END :
 +<code bash>
 +awk '/BEGIN/,/END/' FILE.txt
 +</code> 
 +
 +  * supprimer (ne pas afficher) les doublons de lignes dans un fichier :
 +<code bash>
 +awk '!x[$0]++' test.tmp
 +</code>
 +
 +  * quitter la boucle awk après le premier match
 +<code bash>
 +echo -e "toto\ntoto\n" | awk '/toto/ {print; exit}'
 + toto
 +</code>
 +
 +  * émuler la fonction trim (efface les espaces avant et après une chaine) :
 +<code bash>
 +echo -e "toto   :titi\n   tata:tutu" | \
 + awk -F\: '{ sub(/^[ \t\r\n]+/, "", $1);sub(/[ \t\r\n]+$/, "", $1);print "\""$1"\""}'
 +</code>
informatique/linux/awk.txt · Last modified: 2022/04/13 13:03 by pteu