Comment utiliser le langage AWK pour manipuler du texte dans Linux

Introduction

Les utilitaires Linux suivent souvent la philosophie de conception Unix. On encourage à faire des outils petits, à utiliser des fichiers texte simples en entrée et en sortie, et à fonctionner de manière modulaire. En raison de cet héritage, nous disposons d’une grande fonctionnalité de traitement de texte avec des outils comme sed et awk.

awk est à la fois un langage de programmation et un processeur de texte que vous pouvez utiliser pour manipuler les données textuelles de manière très utile. Dans ce guide, vous explorerez comment utiliser l’outil en ligne de commande awk et comment l’utiliser pour traiter du texte.

Syntaxe de base

La commande awk est incluse par défaut dans tous les systèmes Linux modernes, donc vous n’avez pas besoin de l’installer pour commencer à l’utiliser.

awk est particulièrement utile lorsqu’il s’agit de manipuler des fichiers texte formatés de manière prévisible. Par exemple, il est excellent pour l’analyse et la manipulation de données tabulaires. Il fonctionne ligne par ligne et itère à travers tout le fichier.

Par défaut, il utilise les espaces (espaces, tabulations, etc.) pour séparer les champs. Heureusement, de nombreux fichiers de configuration sur votre système Linux utilisent ce format.

Le format de base d’une commande awk est le suivant :

  1. awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse

Vous pouvez omettre soit la partie de recherche soit la partie d’action de n’importe quelle commande awk. Par défaut, si la partie « action » n’est pas spécifiée, l’action entreprise est « print ». Cela imprime simplement toutes les lignes qui correspondent.

Si la partie de recherche n’est pas spécifiée, awk exécute l’action indiquée sur chaque ligne.

Si les deux sont spécifiés, awk utilise la partie de recherche pour décider si la ligne actuelle reflète le motif, puis exécute les actions sur les correspondances.

Dans sa forme la plus simple, vous pouvez utiliser awk comme cat pour imprimer toutes les lignes d’un fichier texte à l’écran.

Créez un fichier favorite_food.txt qui répertorie les plats préférés d’un groupe d’amis :

  1. echo "carrot sandy
  2. wasabi luke
  3. sandwich brian
  4. salad ryan
  5. spaghetti jessica" > favorite_food.txt

Utilisez maintenant la commande awk pour imprimer le fichier à l’écran :

  1. awk '{print}' favorite_food.txt

Vous verrez le fichier imprimé à l’écran :

Output
carrot sandy wasabi luke sandwich brian salad ryan spaghetti jessica

Ce n’est pas très utile. Essayons maintenant les capacités de filtrage de recherche de awk en recherchant dans le fichier le texte « sand » :

  1. awk '/sand/' favorite_food.txt
Output
carrot sandy sandwich brian

Comme vous pouvez le voir, awk n’imprime désormais que les lignes contenant les caractères « sand ».

En utilisant des expressions régulières, vous pouvez cibler des parties spécifiques du texte. Pour n’afficher que la ligne commençant par les lettres « sand », utilisez l’expression régulière ^sand :

  1. awk '/^sand/' favorite_food.txt

Cette fois, une seule ligne est affichée :

Output
sandwich brian

De même, vous pouvez utiliser la section d’action pour spécifier quelles informations vous souhaitez imprimer. Par exemple, pour imprimer uniquement la première colonne, utilisez la commande suivante :

  1. awk '/^sand/ {print $1;}' favorite_food.txt
Output
sandwich

Vous pouvez référencer chaque colonne (délimitée par des espaces) par des variables associées à leur numéro de colonne. Par exemple, la première colonne est $1, la deuxième est $2, et vous pouvez référencer l’ensemble de la ligne avec $0.

Variables internes et format étendu

La commande awk utilise certaines variables internes pour assigner certaines informations lors du traitement d’un fichier.

Les variables internes utilisées par awk sont :

  • FILENAME : Fait référence au fichier d’entrée actuel.
  • FNR : Fait référence au numéro de l’enregistrement actuel par rapport au fichier d’entrée actuel. Par exemple, si vous avez deux fichiers d’entrée, cela vous indiquerait le numéro d’enregistrement de chaque fichier plutôt que le total.
  • FS : Le séparateur de champ actuel utilisé pour indiquer chaque champ dans un enregistrement. Par défaut, il est défini sur un espace blanc.
  • NF : Le nombre de champs dans l’enregistrement actuel.
  • NR : Le numéro de l’enregistrement actuel.
  • OFS : Le séparateur de champ pour les données de sortie. Par défaut, il est défini sur un espace blanc.
  • ORS : Le séparateur d’enregistrement pour les données de sortie. Par défaut, il s’agit d’un caractère de nouvelle ligne.
  • RS: Le séparateur d’enregistrement utilisé pour distinguer les enregistrements séparés dans le fichier d’entrée. Par défaut, il s’agit d’un caractère de nouvelle ligne.

Vous pouvez modifier les valeurs de ces variables à volonté pour correspondre aux besoins de vos fichiers. Habituellement, vous le faites pendant la phase d’initialisation de votre traitement.

Cela nous amène à un autre concept important. La syntaxe awk est légèrement plus complexe que ce que vous avez utilisé jusqu’à présent. Il existe également des blocs optionnels BEGIN et END qui peuvent contenir des commandes à exécuter avant et après le traitement du fichier, respectivement.

Cela rend notre syntaxe étendue quelque chose comme ceci :

  1. awk 'BEGIN { action; }
  2. /search/ { action; }
  3. END { action; }' input_file

Les mots-clés BEGIN et END sont des ensembles spécifiques de conditions, tout comme les paramètres de recherche. Ils correspondent avant et après que le document ait été traité.

Cela signifie que vous pouvez modifier certaines des variables internes dans la section BEGIN. Par exemple, le fichier /etc/passwd est délimité par des deux-points (:) au lieu des espaces blancs.

Pour imprimer la première colonne de ce fichier, exécutez la commande suivante :

  1. awk 'BEGIN { FS=":"; }
  2. { print $1; }' /etc/passwd
Output
root daemon bin sys sync games man . . .

Vous pouvez utiliser les blocs BEGIN et END pour imprimer des informations sur les champs que vous imprimez. Utilisez la commande suivante pour transformer les données du fichier en tableau, joliment espacé avec des onglets en utilisant \t :

  1. awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
  2. {print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
  3. END { print "---------\nFile Complete" }' /etc/passwd

Vous verrez cette sortie :

Output
User UID GID Home Shell -------------- root 0 0 /root /bin/bash daemon 1 1 /usr/sbin /bin/sh bin 2 2 /bin /bin/sh sys 3 3 /dev /bin/sh sync 4 65534 /bin /bin/sync . . . --------- File Complete

Comme vous pouvez le voir, vous pouvez formater les choses assez joliment en profitant de certaines des fonctionnalités de awk.

Chacune des sections étendues est facultative. En fait, la section d’action principale elle-même est facultative si une autre section est définie. Par exemple, vous pouvez faire des choses comme ceci :

  1. awk 'BEGIN { print "We can use awk like the echo command"; }'

Et vous verrez cette sortie :

Output
We can use awk like the echo command

Maintenant, voyons comment rechercher du texte dans les champs de la sortie.

Recherche de champs et expressions composées

Dans l’un des exemples précédents, vous avez imprimé la ligne dans le fichier favorite_food.txt qui commençait par « sand ». C’était facile parce que vous recherchiez le début de toute la ligne.

Et si vous vouliez savoir si un motif de recherche correspondait au début d’un champ au lieu de cela ?

Créez une nouvelle version du fichier favorite_food.txt qui ajoute un numéro d’article devant la nourriture de chaque personne :

  1. echo "1 carrot sandy
  2. 2 wasabi luke
  3. 3 sandwich brian
  4. 4 salad ryan
  5. 5 spaghetti jessica" > favorite_food.txt

Si vous voulez trouver tous les aliments de ce fichier qui commencent par « sa », vous pourriez commencer par essayer quelque chose comme ceci :

  1. awk '/sa/' favorite_food.txt

Cela montre toutes les lignes qui contiennent « sa » :

Output
1 carrot sandy 2 wasabi luke 3 sandwich brian 4 salad ryan

Ici, vous faites correspondre n’importe quelle instance de « sa » dans le mot. Cela inclut des choses comme « wasabi » qui ont le motif au milieu, ou « sandy » qui n’est pas dans la colonne que vous voulez. Dans ce cas, vous êtes seulement intéressé par les mots commençant par « sa » dans la deuxième colonne.

Vous pouvez dire à awk de ne correspondre qu’au début de la deuxième colonne en utilisant cette commande :

  1. awk '$2 ~ /^sa/' favorite_food.txt

Comme vous pouvez le voir, cela nous permet de rechercher uniquement au début de la deuxième colonne pour une correspondance.

La partie field_num ~ spécifie que awk doit seulement tenir compte de la deuxième colonne.

Output
3 sandwich brian 4 salad ryan

Vous pouvez tout aussi facilement rechercher des éléments qui ne correspondent pas en incluant le caractère « ! » avant le tilde (~). Cette commande renverra toutes les lignes qui n’ont pas de nourriture commençant par « sa » :

  1. awk '$2 !~ /^sa/' favorite_food.txt
Output
1 carrot sandy 2 wasabi luke 5 spaghetti jessica

Si vous décidez plus tard que vous vous intéressez uniquement aux lignes qui ne commencent pas par « sa » et que le numéro d’élément est inférieur à 5, vous pourriez utiliser une expression composée comme ceci :

  1. awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt

Cela introduit quelques nouveaux concepts. Le premier est la possibilité d’ajouter des exigences supplémentaires pour que la ligne corresponde en utilisant l’opérateur &&. En utilisant cela, vous pouvez combiner un nombre arbitraire de conditions pour que la ligne corresponde. Dans ce cas, vous utilisez cet opérateur pour ajouter une vérification que la valeur de la première colonne est inférieure à 5.

Vous verrez cette sortie :

Output
1 carrot sandy 2 wasabi luke

Vous pouvez utiliser awk pour traiter des fichiers, mais vous pouvez également travailler avec la sortie d’autres programmes.

Traitement de la sortie d’autres programmes

Vous pouvez utiliser la commande awk pour analyser la sortie d’autres programmes plutôt que de spécifier un nom de fichier. Par exemple, vous pouvez utiliser awk pour extraire l’adresse IPv4 de la commande ip.

La commande ip a affiche l’adresse IP, l’adresse de diffusion et d’autres informations sur toutes les interfaces réseau de votre machine. Pour afficher les informations pour l’interface appelée eth0, utilisez cette commande:

  1. ip a s eth0

Vous verrez les résultats suivants:

Output
2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever

Vous pouvez utiliser awk pour cibler la ligne inet et ensuite imprimer uniquement l’adresse IP:

  1. ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'

Le drapeau -F indique à awk de délimiter par des barres obliques ou des espaces en utilisant l’expression régulière [\/ ]+. Cela divise la ligne inet 172.17.0.11/16 en champs séparés. L’adresse IP se trouve dans le troisième champ car les espaces au début de la ligne comptent également comme un champ, puisque vous avez délimité par des espaces ainsi que des barres obliques. Notez que awk traite les espaces consécutifs comme un seul espace dans ce cas.

La sortie affiche l’adresse IP:

Output
172.17.0.11

Vous trouverez de nombreux endroits où vous pouvez utiliser awk pour rechercher ou analyser la sortie d’autres commandes.

Conclusion

À ce stade, vous devriez avoir une compréhension de base de comment vous pouvez utiliser la commande awk pour manipuler, formater et imprimer sélectivement des fichiers texte et des flux de texte. Awk est cependant un sujet beaucoup plus vaste, et c’est en fait un langage de programmation complet avec affectation de variables, structures de contrôle, fonctions intégrées, et plus encore. Vous pouvez l’utiliser dans vos propres scripts pour formater du texte de manière fiable.

Pour en savoir plus sur awk, vous pouvez lire le livre du domaine public gratuit de ses créateurs qui va beaucoup plus en détail.

Source:
https://www.digitalocean.com/community/tutorials/how-to-use-the-awk-language-to-manipulate-text-in-linux