Article de reference

AWK

{{cite web|url=https://www6.software.ibm.com/developerworks/education/au-gawk/au-gawk-a4.pdf|title=Get started with GAWK: AWK language fundamentals|last=Stutz|first=Michael|date...

langage de script conçu pour le traitement de texte et généralement utilisé comme outil d'extraction et de génération de rapports de données . À instar de sed et grep , il s'agit d'un filtre [ d'une fonctionnalité standard de la plupart des systèmes d'exploitation de type Unix . La commande shell qui exécute le processeur AWK est nommée `awk` .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 :

expression régulière à une chaîne de caractères. Par commodité syntaxique , `/regexp/` sans utiliser l'opérateur tilde effectue une recherche sur l'enregistrement courant ; cette syntaxe provient de `sed` , qui l'a lui-même héritée de l' éditeur `ed`/ , 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 :

> "nom de fichier" }

ou par un tuyau :

| "commande" }

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 :

imprimer 331 % - 79impression - 3,31e-11 % 7,9e-23impression 331 / 79imprimer ( 331 - 331 % 79 ) / 79} '15- 1,1999020635259e-234,18987341772154

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.

") et uniquement les guillemets doubles délimitent les chaînes de caractères constantes. Les instructions et/ou expressions n'ont pas besoin de se terminer par un point-virgule. En fait, le point-virgule ;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.

espace avant les variables locales dans la liste des arguments pour marquer la limite entre les paramètres et les variables locales.

Exemples

Bonjour le monde!

Voici le programme habituel « Hello, World ! » écrit en AWK :

exit }

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.

80 "
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 ) :

priorité$ 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

, NR , $ 0 }

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 :

} { pour ( i = 1 ; i <= NF ; i ++ ) mots [ en minuscules ( $ i )] ++ } FIN { pour ( i dans mots ) afficher i , mots [ i ] }

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 :

$1 " décalage awk '/' " $pattern " '/ { print FILENAME ":" $0 }' " $@ "

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 :

$1 " shift awk '$0 ~ ENVIRON["pattern"] { print FILENAME ":" $0 }' " $@ "

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 :

$1 " décalage awk '$0 ~ motif { print FILENAME ":" $0 }' motif = " $motif " " $@ "

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 :

} } $ 0 ~ motif { print FILENAME ":" $ 0 }

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 :

la version 7 d'Unix .

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 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.

  • mawk est une implémentation AWK très rapide de Mike Brennan, basée sur un interpréteur de bytecode .
  • libmawk est une version dérivée de mawk, permettant aux applications d'intégrer plusieurs instances parallèles d'interpréteurs awk.
  • Awka (dont l'interface est basée sur le programme mawk ) est un autre traducteur de scripts AWK en code C. Après compilation, avec l'inclusion statique de la bibliothèque libawka.a de l'auteur, les exécutables obtenus sont considérablement plus rapides et, d'après les tests de l'auteur, leurs performances sont très comparables à celles d'autres versions d'AWK, de Perl ou de Tcl . De petits scripts sont ainsi transformés en programmes de 160 à 170 ko.
  • tawk (Thompson AWK) est un compilateur AWK pour Solaris , MS-DOS , OS/2 et Windows , vendu par Thompson Automation Software (défunt).
  • Jawk est un projet visant à implémenter AWK en Java , hébergé sur SourceForge. Des extensions au langage sont ajoutées pour fournir un accès aux fonctionnalités Java dans les scripts AWK (c'est-à-dire les threads Java, les sockets, les collections, etc.).
  • xgawk est une version dérivée de gawk qui étend gawk avec des bibliothèques chargeables dynamiquement. L'extension XMLgawk a été intégrée à la version officielle 4.1.0 de GNU Awk.
  • Hawk est un interpréteur AWK embarqué écrit en C et hébergé sur Github . Il a commencé sous le nom de QSEAWK , un interpréteur AWK embarqué inclus dans la bibliothèque QSE.
  • libfawk est un interpréteur très petit, fonctionnel uniquement, réentrant et embarquable, écrit en C.
  • BusyBox inclut une implémentation AWK écrite par Dmitry Zakharov. Il s'agit d'une implémentation très compacte, adaptée aux systèmes embarqués.
  • CLAWK de Michael Parker fournit une implémentation AWK en Common Lisp , basée sur la bibliothèque d'expressions régulières du même auteur.
  • goawk est une implémentation AWK en Go avec quelques extensions pratiques par Ben Hoyt, hébergée sur Github .
  • Le manuel de gawk contient une liste d'autres implémentations AWK.

    Livres

    Plus d articles de Worldlex Wiki

    Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

    Explorer l index