-- Leo's gemini proxy

-- Connecting to bwog-notes.chagratt.site:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

Awk


Rédigé le 21 février 2017 - modifié le 15 novembre 2022. Étiquettes : shell


awk est une commande complexe mais puissante. Du coup je lui consacre maintenant une page dédiée.




Filtrer les lignes


On peut avoir pour habiture de chaîner cat et grep avant d'utiliser awk, mais c'est inutile.

En effet, il est possible de tout faire avec awk, ce qui est bien plus efficace.


Par exemple, on peut remplacer :


cat mon_fichier | grep toto | awk '{ print $1 }'

par :


awk '/toto/ { print $1 }' mon_fichier

Filtrer les lignes, en fonction d'un champ


Il est possible d'utiliser les _REGEX_ ou te faire de la comparaison de chaîne simple sur un champ particulier.


Exemple pour afficher les process zombies de la machine (et le père) :


ps -elf | awk '$2 ~ /Z/ {print $2 " : " $4 " - PPID : " $5}'
# ou bien
ps -elf | awk '$2 == "Z" {print $2 " : " $4 " - PPID : " $5}'

Transmettre des variables depuis le shell


On peut tenter d'utiliser l'extrapolation depuis le shell, mais c'est franchement sale, et bancal.


Plus simple et robuste : l'option -v var=VALEUR.

Cette variable existera sous le nom var dans le script awk.

La valeur peut-être fixe, mais aussi peut provenir du shell si besoin :


bar="baz"
awk -v foo="${bar}" '$2 == foo {print $0}' mon_fichier

Répéter plusieurs fois, avec un nom unique pour injecter plusieurs variables.


Exclure des lignes mais en inclure d'autres


Un titre de section pas terrible qui cache un cas qui peut arriver plus souvent qu'on ne le croit.


Typiquement, il arrive qu'on ait un fichier contenant des noms puis plusieurs propriétés, exemple :

des serveurs avec les environnements utilisés, les programmes majeurs qui tournent dessus, l'OS, etc.

Et qu'on veuille récupérer tous les serveurs d'un OS spécifique qui sont en dehors de la production.


Une manière de le faire est de chainer les comparaisons : ($0 !~ exclude_criteria) && ($0 ~ include_criteria).


On peut même le coupler avec l'option -v pour passer des variables et filtrer dessus :


awk '($0 !~ "PROD") && ($0 ~ "Linux") {print $0}' mon_fichier
# plus long, mais plus lisible :
awk -v exclude='PROD' -v include='Linux' '($0 !~ exclude) && ($0 ~ include) {print $0}' mon_fichier

Choisir un champ depuis la fin


En fonction du nombre de champs,

plutôt que de se retrouver avec des $6, $9 ou plus,

on peur jouer avec $NF en lui passant une soustraction.


La syntaxe est : $(NF-n), avec n un entier.


Exemple :


awk '{ print $(NF-2) }' "mon_fichier"


Séparateur


Pour changer le séparateur de champ, il existe deux moyens.


Méthode 1


Utiliser l'argument -F en lui donnant le caractère de séparation.

Exemple :


awk -F ';' '{print $7}' fichier.csv

Méthode 2


Un peu plus long, mais utile dans le cas d'un script en pur awk :


ajouter BEGIN { FS = "REGEX" } avant le motif d'extraction.

Exemple, pour extraire le 7è champ d'un CSV délimité par des points-virgules :


awk 'BEGIN { FS = ";" } ; {print $7}' fichier.csv

Notez que la variable FS (interne à awk) n'a rien à voir avec IFS de votre shell.


-------------------------------

← Plus récent : Le thème s'assombrit

→ Plus ancien : Faire un dépôt/miroir pip local

Aléatoire : Mise à jour de Février

Retour à l'accueil


Contenu sous licence CC-BY-SA


-- Response ended

-- Page fetched on Sat May 18 07:07:06 2024