AWK est utilisé pour la manipulation de fichiers textuels pour des opérations de recherches, de remplacement et de transformations complexes.
awk s'utilise de cette façon:
-F<sep> : Sert à définir le séparateur de champ. Cette option est facultative.
On développera plus tard, c'est plus simple d'apprendre par l'exemple !
On développera plus tard, c'est plus simple d'apprendre par l'exemple !
J'aime bien l'apprentissage par l'exemple, allons-y progressivement !
Prenons par exemple la commande ps, elle me retourne ceci :
Si on souhaite n'afficher que la première colonne :
Le résultat sera :
Par défaut c'est l'espace/tabulation le séparateur de champ. On pourra le modifier avec -F.
Exemple avec le fichier /etc/passwd qui contient la liste des utilisateurs, leur shell, leur dossier personnel. Pour récupérer la première colone :
Si vous voulez afficher plusieurs champs, plusieurs possibilités :
ou
Avec le premier exemple, vous constatez que le séparateur de sortie (pour l'affichage) c'est l'espace. On peut le redéfinir avec OFS ainsi :
Avec le deuxième exemple, on voit que le texte se met entre guillemets. Voici un exemple avec plus de texte :
On peut ajouter des conditions rapides, ici récupérons que les comptes utilisateurs (UID >= 1000 , champ 3) :
Pour effectuer une recherche dans un fichier ou une sortie de commande, on pourra utiliser le motif de recherche entre deux barres obliques :
Exemple, la sortie de la commande df sur ma machine :
Code TEXT :Sys. de fichiers blocs de 1K Utilisé Disponible Uti% Monté sur
devtmpfs 10240 0 10240 0% /dev
shm 8204460 545788 7658672 7% /dev/shm
tmpfs 8204460 1624 8202836 1% /run
/dev/mapper/rootvg-root 66956728 39494728 27131044 60% /
cgroup_root 10240 0 10240 0% /sys/fs/cgroup
/dev/sda2 1011144 187806 808767 19% /boot
/dev/sda1 100808 249 100560 1% /boot/efi
/dev/mapper/rootvg-home 143972492 102341848 40460828 72% /home
/dev/sdb1 1921811248 1713668144 188591588 91% /media/DATA
/dev/mapper/rootvg-vmssd 87468064 21141316 66257936 25% /media/SSD
tmpfs 1640892 28 1640864 1% /run/user/1000
Si je ne veux filtrer que les lignes concernant mes volumes logiques (qui contiennent le mot mapper) :
Ici on affichera les colonnes 1 et 5.
Mais on peut afficher toute la ligne ! Cela se fait avec $0 :
On peut cumuler des filtres et des filtres inverses avec la négation, symbole point d'exclamation. Ici filtre avec les lignes mapper qui ne contiennent pas vm :
On peut aussi faire des calculs, ici, j'affiche la colonne 1 et la somme de la 3ème et la 4ème (dans df c'est le Utilisé et le Disponible, donc ça nous génère la taille totale du volume) :
Autre exemple avec ici, avec une condition sur le premier champ, et l'ajout d'une fonction int qui permet d'arrondir le calcul :
On peut utiliser plusieurs choses dans la fonction AWK, il suffit de séparer toutes les instructions avec des point virgules :
On va prendre d'autres exemples sur le fichier /etc/shells qui contient la liste des shell dispo sur la machine.
On va afficher le nom du shell. Le but est donc de filtrer les lignes commençant par /, d'utiliser ce séparateur / et d'afficher le dernier champ.
NF correspondant au nombre de champs, s'il y en a 3, $NF vaudra donc $3 :
Remarquez l'échappement du slash avec un anti-slash !
Il existe une fonction qui permet de calculer une longueur de chaîne. Ici on va afficher les lignes de plus de 8 caractères :
Repartons avec la commande ps.
On va afficher les lignes dont le dernier champ est /bin/bash, mixons donc conditions et NF vu précédemment :
Avec les conditions, on peut utiliser les match et les expressions régulières :
Exemple : Afficher toutes les lignes de notre config kernel commençant par CONFIG :
On peut utiliser la fonction substring pour ici, afficher à partir du 8ème caractère :
Le match peut aussi se faire avec la fonction match. Ça nous permet d’utiliser RSTART qui nous indique la position du premier caractère qui match avec l'expression de la fonction match :
awk 'match($0, /EXT4/) { print $0 " a la chaine EXT4 à la position " RSTART}' /boot/config-5.4.80-gentoo-r1-adrien
On a aussi NR pour Number Record. On pourra l'utiliser ainsi, pour n'afficher que les 6 premières lignes :
Pour afficher le nombre de lignes d'un fichier, on cherchera avec END :
Ah ouais et un truc marrant, on peut scripter avec des fonctions basiques.
Voici un exemple qui ne sert à rien, mais qui vous illustre les possibilités :