langage de script piloté par les données , constitué d'un ensemble d'actions à effectuer sur des flux de données textuelles – soit directement sur des fichiers, soit au sein d'un pipeline – afin d'extraire ou de transformer du texte, par exemple pour produire des rapports formatés. Ce langage utilise abondamment le type de données chaîne de caractères , les tableaux associatifs (c'est-à-dire des tableaux indexés par des chaînes de caractères clés) et les expressions régulières . Bien qu'AWK ait un domaine d'application limité et ait été conçu spécifiquement pour les programmes en une seule ligne , il est Turing-complet , et même les premiers utilisateurs d'AWK chez Bell Labs écrivaient souvent des programmes AWK volumineux et bien structurés. AWK a été créé aux Bell Labs dans les années 1970 , et son nom est dérivé des noms de famille de ses auteurs : Alfred Aho (auteur d’ egrep ), Peter Weinberger (qui a travaillé sur les bases de données relationnelles de petite taille) et Brian Kernighan . L’acronyme se prononce comme le nom de l’espèce d’oiseau pingouin , illustrée sur la couverture de l’ouvrage *The AWK Programming Language * .
Marc Rochkind , utilisé pour rechercher des motifs dans les données d'entrée, et était implémenté à l'aide de yacc . AWK , l'un des premiers outils apparus dans Unix version 7 , a ajouté des fonctionnalités de calcul au pipeline Unix, en complément du shell Bourne , seul langage script disponible dans un environnement Unix standard. Il fait partie des utilitaires obligatoires de la spécification Single UNIX [ et est requis par la spécification Linux Standard Base .
En 1983, AWK était l'un des nombreux outils UNIX disponibles pour le système d'exploitation UNOS de Charles River Data Systems sous licence des Laboratoires Bell .
AWK a fait l'objet d'une révision et d'une extension importantes entre 1985 et 1988, aboutissant à l' implémentation GNU AWK écrite par Paul Rubin, Richard Stallman , et publiée en 1988. GNU AWK est probablement la version la plus répandue car elle est incluse dans les paquets Linux basés sur GNU. Depuis 1994, Le code source de nawk (New AWK) de Brian Kernighan a d'abord été publié en 1993 sans publicité, puis publiquement à la fin des années 1990 ; de nombreux systèmes BSD l'utilisent pour contourner la licence GPL.
AWK a été précédé par sed (1974). Tous deux ont été conçus pour le traitement de texte. Ils partagent le paradigme orienté ligne et piloté par les données, et sont particulièrement adaptés à l'écriture de programmes concis , grâce à la boucle principale implicite et aux variables de ligne courante. La puissance et la concision des premiers programmes AWK – notamment la gestion performante des expressions régulières et la concision due aux variables implicites, qui facilitent l'écriture de programmes concis – ainsi que les limitations d'AWK à l'époque, ont fortement inspiré le langage Perl (1987). Dans les années 1990, Perl a connu un grand succès, concurrençant AWK sur le marché des langages de traitement de texte Unix.
Structure des programmes AWK

AWK lit l'entrée ligne par ligne. Chaque ligne est analysée à la recherche d'un motif dans le programme, et pour chaque motif correspondant, l'action associée est exécutée.
— Alfred V. Aho
Un programme AWK est une série de paires d'actions et de modèles, écrites comme suit :
/ , où `\` est utilisé pour la recherche. Cette syntaxe utilisant des barres obliques comme délimiteurs pour les expressions régulières a ensuite été adoptée par Perl et ECMAScript , et est aujourd'hui courante. L'opérateur tilde a également été adopté par Perl.Commandes
Les commandes AWK sont les instructions qui remplacent les actions dans les exemples ci-dessus. Elles peuvent inclure des appels de fonctions, des affectations de variables, des calculs, ou toute combinaison de ces éléments. AWK intègre de nombreuses fonctions ; les différentes versions d'AWK en proposent bien d'autres. De plus, certaines versions permettent l'utilisation de bibliothèques liées dynamiquement , qui peuvent également fournir des fonctions supplémentaires.
La commande d'impression
La commande print permet d'afficher du texte. Ce texte est toujours terminé par une chaîne prédéfinie appelée séparateur d'enregistrements de sortie (ORS), dont la valeur par défaut est un saut de ligne. La forme la plus simple de cette commande est :
print- Ceci affiche le contenu de l'enregistrement actuel. En AWK, les enregistrements sont divisés en champs , et ceux-ci peuvent être affichés séparément :
print $1- Affiche le premier champ de l'enregistrement actuel
print $1, $3- Affiche le premier et le troisième champ de l'enregistrement actuel, séparés par une chaîne prédéfinie appelée séparateur de champs de sortie (OFS), dont la valeur par défaut est un espace.
Bien que ces champs ( $X ) puissent ressembler à des variables (le symbole $ indique les variables dans les shells Unix classiques et en Perl ), ils font en réalité référence aux champs de l'enregistrement courant. Un cas particulier, $0 , fait référence à l'enregistrement entier. En fait, les commandes «print » et «print $0 » ont la même fonctionnalité.
La commande d'impression peut également afficher les résultats de calculs et/ou d'appels de fonctions :
ou par un tuyau :
Variables intégrées
Les variables intégrées d'AWK comprennent les variables de champ : $1, $2, $3, etc. ($0 représente l'enregistrement entier). Elles contiennent le texte ou les valeurs des champs de texte individuels d'un enregistrement.
Parmi les autres variables, on peut citer :
NRNombre d'enregistrements. Conserve le nombre actuel d'enregistrements lus à ce jour dans tous les fichiers de données. Il commence à zéro, mais n'est jamais automatiquement remis à zéro.FNR: Nombre d'enregistrements du fichier. Conserve le nombre actuel d'enregistrements lus dans le fichier courant. Cette variable est automatiquement remise à zéro à chaque ouverture d'un nouveau fichier.NFNombre de champs : Indique le nombre de champs dans l’enregistrement d’entrée actuel. Le dernier champ de l’enregistrement d’entrée peut être désigné par $NF, l’avant-dernier par $(NF-1), le troisième avant-dernier par $(NF-2), etc.FILENAME: Contient le nom du fichier d'entrée actuel.FSSéparateur de champs. Contient le « séparateur de champs » utilisé pour diviser les champs dans l'enregistrement d'entrée. Par défaut, il s'agit d'un espace blanc, mais toute séquence d'espaces et de tabulations est autorisée. Vous pouvez remplacer le séparateur de champs par un autre caractère ou une autre séquence de caractères.RSSéparateur d'enregistrements : Stocke le caractère de séparation d'enregistrements actuel. Par défaut, une ligne d'entrée correspond à un enregistrement d'entrée ; le caractère de séparation d'enregistrements par défaut est donc un saut de ligne.OFSSéparateur de champs de sortie. Stocke le séparateur de champs de sortie, utilisé pour séparer les champs lors de leur affichage par awk. La valeur par défaut est un espace.ORSSéparateur d'enregistrements de sortie. Stocke le « séparateur d'enregistrements de sortie », qui sépare les enregistrements de sortie lors de leur affichage par awk. La valeur par défaut est un caractère de nouvelle ligne.OFMTFormat de sortie. Enregistre le format de sortie numérique. Le format par défaut est « %.6g ».
Variables et syntaxe
À l'exception des mots-clés du langage, les noms de variables peuvent utiliser n'importe lequel de ces caractères à condition qu'ils ne commencent pas par un chiffre :
Cette int( dividend / divisor )approche peut engendrer des cas limites d'arrondi incorrect. Pour la concaténation de chaînes , il suffit de placer deux variables (ou constantes de chaîne) l'une à côté de l'autre. L'espace est facultatif pour les constantes de chaîne, mais il est obligatoire entre deux noms de variables consécutifs. Contrairement aux shells Unix ou à d'autres langages comme Perl, le nom de variable sans symbole, composé d'un seul trait de soulignement ( _), n'est ni réservé ni spécial et peut être utilisé librement. Sa valeur par défaut étant la valeur spéciale AWK NULL, qui correspond à la fois à zéro et à la chaîne vide, elle pourrait même servir $_d'alias pour en Perl $0.
;est absolument indispensable uniquement dans la variante à trois arguments de la for ()boucle, qui ressemble beaucoup à son équivalent dans [ C/C++référence manquante]. Tous les arguments non-tableaux des fonctions sont passés « par valeur », ce qui leur permet d'être librement modifiés par la fonction tout en garantissant l'absence d'effets de bord pour la fonction appelante.Contrairement à Python, toutes les affectations augmentées, awktelles que celles mentionnées ici, +=-=*=/=^=%=sont des expressions. Ceci permet un chaînage efficace de longueur illimitée. L'un de ses principaux avantages est illustré par l'algorithme de calcul des nombres de Fibonacci, dont la complexité est de O(n²) O(n) car il s'incrémente sur lui-même. a += b += a += b += a += b += ... Pour les 77 premiers nombres de Fibonacci environ, cette approche est très efficace, car elle évite d'avoir à examiner des bits, à permuter des variables ou à subir la surcharge de la récursion.
Enfin, des commentaires peuvent être ajoutés aux programmes en utilisant « » #comme premier caractère sur une ligne, ou après une commande ou une séquence de commandes.
Fonctions définies par l'utilisateur
Dans un format similaire à celui du C , les définitions de fonctions se composent du mot-clé ` functionfunction`, du nom de la fonction, des noms des arguments et du corps de la fonction. Voici un exemple de fonction.
Exemples
Bonjour le monde!
Voici le programme habituel « Hello, World ! » écrit en AWK :
Imprimer les lignes de plus de 80 caractères
Imprimer toutes les lignes de plus de 80 caractères. Par défaut, imprimer la ligne courante.
longueur ( 0 $ ) > 80
Compter les mots
Comptez les mots dans l'entrée et affichez le nombre de lignes, de mots et de caractères (comme wc ) :
$ maximale . (Si la ligne ne contient aucun champ, alors vaut 0, représente la ligne entière, qui dans ce cas est vide à l'exception d'éventuels espaces, et a donc la valeur numérique 0.)NF$0À la fin de l'entrée, le ENDmotif correspond et sest donc affiché. Cependant, comme il se peut qu'aucune ligne n'ait été saisie, auquel cas aucune valeur n'a jamais été attribuée à la variable s, scelle-ci sera par défaut une chaîne vide. Ajouter zéro à une variable est une convention AWK permettant de la convertir d'une chaîne de caractères en une valeur numérique. Ceci est dû au fait que les opérateurs arithmétiques d'AWK, comme l'addition, convertissent implicitement leurs opérandes en nombres avant le calcul, si nécessaire. (De même, concaténer une variable avec une chaîne vide la convertit d'un nombre en une chaîne, par exemple : « nombre » s "". Notez qu'il n'existe pas d'opérateur pour concaténer des chaînes ; elles sont simplement placées côte à côte.) Sur une entrée vide, la conversion dans ` { print s + 0 }concat` provoque l'affichage de « nombre » 0, tandis qu'avec la seule action `concat` { print s }, une ligne vide serait affichée.
Faites correspondre une gamme de lignes d'entrée
L'instruction d'action affiche chaque ligne numérotée. La fonction `printf` émule la fonction `printf` standard du C et fonctionne de manière similaire à la commande `print` décrite précédemment. Le motif à rechercher fonctionne cependant comme suit : `NR` représente le nombre d'enregistrements (généralement des lignes d'entrée) que AWK a lus jusqu'à présent, c'est-à-dire le numéro de ligne courant, en commençant par 1 pour la première ligne d'entrée. ` %` est l' opérateur modulo . `NR % 4 == 1` est vrai pour les lignes 1, 5, 9, etc. d'entrée. De même, `NR % 4 == 3` est vrai pour les lignes 3, 7, 11, etc. d'entrée. Le motif de plage est faux jusqu'à ce que la première partie corresponde (ligne 1), puis reste vrai jusqu'à ce que la deuxième partie corresponde (ligne 3). Il reste ensuite faux jusqu'à ce que la première partie corresponde à nouveau (ligne 5).
Le programme affiche donc les lignes 1, 2 et 3, ignore la ligne 4, puis les lignes 5, 6 et 7, et ainsi de suite. Pour chaque ligne, il affiche le numéro de ligne (sur un champ de 6 caractères) suivi de son contenu. Par exemple, avec l'entrée suivante :
Rome Florence Milan Naples Turin Venise
Le programme précédent affiche :
1 Rome 2 Florence 3 Milan 5 Turin 6 Venise
Impression de la partie initiale ou finale d'un fichier
Dans le cas particulier où la première partie d'un motif de plage est toujours vraie (par exemple, 1) , la plage commence au début de l'entrée. De même, si la seconde partie est toujours fausse (par exemple, 0) , la plage se poursuit jusqu'à la fin de l'entrée. Par exemple :
Calculer les fréquences des mots
Fréquence des mots à l'aide de tableaux associatifs :
Le bloc BEGIN définit le séparateur de champs comme une séquence quelconque de caractères non alphabétiques. Les séparateurs peuvent être des expressions régulières. Ensuite, on arrive à une action simple qui s'applique à chaque ligne d'entrée. Dans ce cas, pour chaque champ de la ligne, on incrémente de un le nombre d'occurrences du mot, préalablement converti en minuscules. Enfin, dans le bloc END, on affiche les mots avec leur fréquence d'apparition.
pour (je en mots)
Cette fonction crée une boucle qui parcourt le tableau `words` , en attribuant à `i` la valeur de chaque indice du tableau. Ceci diffère de la plupart des langages, où une telle boucle parcourt chaque valeur du tableau. La boucle affiche ainsi chaque mot suivi de sa fréquence d'apparition. Cette fonction tolowera été ajoutée à la fonction `awk` originale (voir ci-dessous) après la publication du livre.
Modèle de correspondance à partir de la ligne de commande
Ce programme peut être représenté de plusieurs manières. La première utilise le shell Bourne pour créer un script shell qui effectue toutes les opérations. C'est la plus courte de ces méthodes :
Dans $patternla commande awk, la variable `filename` n'est pas protégée par des guillemets simples, ce qui permet à l'interpréteur de commandes de la développer. Cependant, il est nécessaire de l'entourer de guillemets doubles pour gérer correctement les motifs contenant des espaces. Un motif seul, utilisé de manière classique, vérifie si la ligne entière $0correspond. FILENAME`filename` contient le nom du fichier courant. awk ne possède pas d'opérateur de concaténation explicite ; deux chaînes adjacentes sont concaténées. `filename` $0est développé en la ligne d'entrée originale inchangée.
Il existe d'autres façons d'écrire ceci. Ce script shell accède directement à l'environnement depuis awk :
Il s'agit d'un script shell utilisant `awk.env` ENVIRON, un tableau introduit dans une version plus récente de la bibliothèque awk après la publication du livre. L'indice de `awk.env` ENVIRONcorrespond au nom d'une variable d'environnement ; son résultat est la valeur de cette variable. Ceci est similaire à la fonction `getenv` présente dans diverses bibliothèques standard et dans POSIX . Le script shell crée une variable d'environnement patterncontenant le premier argument, puis supprime cet argument et laisse awk rechercher le motif dans chaque fichier.
~L'opérateur `if` vérifie si son opérande gauche correspond à son opérande droit ; `if` !~est son inverse. Une expression régulière est simplement une chaîne de caractères et peut être stockée dans des variables.
La méthode suivante utilise l'affectation de variables en ligne de commande, dans laquelle un argument de awk peut être considéré comme une affectation à une variable :
Ou vous pouvez utiliser l' option de ligne de commande -v var=valeur (par exemple awk -v pattern="$pattern" ... ).
Enfin, ce code est écrit en awk pur, sans l'aide d'un shell ni la nécessité de trop connaître l'implémentation du script awk (contrairement à l'affectation de variables en ligne de commande), mais il est un peu long :
Il BEGINest nécessaire non seulement d'extraire le premier argument, mais aussi d'empêcher qu'il ne soit interprété comme un nom de fichier après la BEGINfin du bloc. ARGCLe nombre d'arguments est toujours garanti supérieur ou égal à 1, tout comme ARGV[0]le nom de la commande qui a exécuté le script, le plus souvent la chaîne de caractères «"awk" . ». ARGV[ARGC]« . » est une chaîne vide. « . » #initie un commentaire qui s'étend jusqu'à la fin de la ligne.
Notez le ifbloc. awk vérifie uniquement s'il doit lire depuis l'entrée standard avant d'exécuter la commande. Cela signifie que
awk 'prog'
Cela fonctionne uniquement parce que l'absence de noms de fichiers n'est vérifiée qu'avant progl'exécution ! Si vous définissez explicitement la valeur ARGCà 1 pour qu'il n'y ait aucun argument, awk s'arrêtera simplement car il considérera qu'il n'y a plus de fichiers d'entrée. Par conséquent, vous devez indiquer explicitement de lire depuis l'entrée standard avec le nom de fichier spécial `/etc/awk` -.
Scripts AWK autonomes
Sur les systèmes d'exploitation de type Unix, il est possible de construire des scripts AWK autonomes en utilisant la syntaxe shebang .
Par exemple, un script qui envoie le contenu d'un fichier donné vers la sortie standard peut être construit en créant un fichier nommé print.awkavec le contenu suivant :
En 1985, ses auteurs ont commencé à développer le langage, notamment en y ajoutant des fonctions définies par l'utilisateur. Le langage est décrit dans l'ouvrage * The AWK Programming Language* , publié en 1988, et son implémentation a été intégrée aux versions d' UNIX System V. Afin d'éviter toute confusion avec l'ancienne version incompatible, cette version a parfois été appelée « new awk » ou « nawk » . Cette implémentation a été publiée sous licence libre en 1996 et est toujours maintenue par Brian Kernighan (voir les liens externes ci-dessous).UNIX/32V , incluaient Le manuel de gawk contient une liste d'autres implémentations AWK. awkccun programme qui convertissait AWK en C. Kernighan a écrit un programme pour convertir awk en Brian Kernighan . Elle est surnommée « le véritable AWK » en raison de l'utilisation de ce terme en lien avec l'ouvrage qui a décrit le langage à l'origine et du fait que Kernighan était l'un des auteurs originaux d'AWK. FreeBSD désigne cette version sous le nom de one-true-awk . Cette version possède également des fonctionnalités absentes du livre, telles que tolowercelles ENVIRONexpliquées précédemment ; consultez le fichier FIXES dans l'archive source pour plus de détails. Cette version est utilisée, par exemple, par , FreeBSD , NetBSD , OpenBSD , macOS et illumos . Brian Kernighan et Arnold Robbins sont GNU awk) est une autre implémentation libre et la seule qui propose des avancées significatives en matière d' internationalisation, de localisation et de réseau TCP/IP. Elle a été écrite avant que l'implémentation originale ne soit disponible gratuitement. Elle intègre son propre débogueur et son profileur , permettant à l'utilisateur d'optimiser les performances d'un script de manière mesurable. Elle permet également d'étendre ses fonctionnalités grâce à des bibliothèques partagées. Certaines distributions Linux utilisent gawk comme implémentation AWK par défaut. Depuis la version 5.2 (septembre 2022), CSV de gawk fournit des fonctionnalités pour l'entrée et la sortie de données au format CSV. Livres