GNU/Linux >> Tutoriels Linux >  >> Linux

Améliorez vos compétences awk avec deux tutoriels faciles

Awk est l'un des outils les plus anciens de la boîte à outils de l'utilisateur Unix et Linux. Créé dans les années 1970 par Alfred Aho, Peter Weinberger et Brian Kernighan (les A, W et K du nom de l'outil), awk a été créé pour le traitement complexe de flux de texte. C'est un outil complémentaire à sed, l'éditeur de flux, qui est conçu pour le traitement ligne par ligne des fichiers texte. Awk permet des programmes structurés plus complexes et est un langage de programmation complet.

Cet article explique comment utiliser awk pour des tâches plus structurées et complexes, y compris une simple application de publipostage.

Structure du programme Awk

Un script awk est composé de blocs fonctionnels entourés de {} (accolades). Il existe deux blocs de fonction spéciaux, BEGIN et FIN , qui s'exécutent avant de traiter la première ligne du flux d'entrée et après le traitement de la dernière ligne. Entre les deux, les blocs ont le format :

pattern { action statements } 

Chaque bloc s'exécute lorsque la ligne dans le tampon d'entrée correspond au modèle. Si aucun modèle n'est inclus, le bloc fonction s'exécute sur chaque ligne du flux d'entrée.

De plus, la syntaxe suivante peut être utilisée pour définir des fonctions dans awk qui peuvent être appelées depuis n'importe quel bloc :

function name(parameter list) { statements } 

Cette combinaison de blocs et de fonctions de correspondance de modèles permet au développeur de structurer des programmes awk pour la réutilisation et la lisibilité.

Comment awk traite les flux de texte

Awk lit le texte de son fichier d'entrée ou flux une ligne à la fois et utilise un séparateur de champs pour l'analyser en un certain nombre de champs. Dans la terminologie awk, le tampon courant est un enregistrement . Il existe un certain nombre de variables spéciales qui affectent la façon dont awk lit et traite un fichier :

  • FS (séparateur de champs) :par défaut, il s'agit de n'importe quel espace blanc (espaces ou tabulations)
  • RS (séparateur d'enregistrement) :par défaut, une nouvelle ligne (\n )
  • NF (nombre de champs) :lorsque awk analyse une ligne, cette variable est définie sur le nombre de champs qui ont été analysés
  • 0 USD : L'enregistrement actuel
  • 1 $, 2 $, 3 $, etc. : Le premier, deuxième, troisième, etc. champ de l'enregistrement actuel
  • NR (nombre d'enregistrements) :le nombre d'enregistrements analysés jusqu'à présent par le script awk

Il existe de nombreuses autres variables qui affectent le comportement d'awk, mais cela suffit pour commencer.

Awk one-liners

Pour un outil aussi puissant, il est intéressant de noter que la plupart des utilisations d'awk sont des lignes simples de base. Le programme awk le plus courant imprime peut-être des champs sélectionnés à partir d'une ligne d'entrée à partir d'un fichier CSV, d'un fichier journal, etc. Par exemple, le one-liner suivant imprime une liste de noms d'utilisateur à partir de /etc/passwd :

awk -F":" '{print $1 }' /etc/passwd 

Comme mentionné ci-dessus, 1 $ est le premier champ de l'enregistrement en cours. Le -F l'option définit la variable FS sur le caractère  : .

Le séparateur de champs peut également être défini dans un bloc fonction BEGIN :

awk 'BEGIN { FS=":" } {print $1 }' /etc/passwd 

Dans l'exemple suivant, chaque utilisateur dont le shell n'est pas /sbin/nologin peut être imprimé en faisant précéder le bloc d'une correspondance de motif :

awk 'BEGIN { FS=":" } ! /\/sbin\/nologin/ {print $1 }' /etc/passwd 

Awk avancé :Fusion et publipostage

Maintenant que vous avez quelques notions de base, essayez d'approfondir awk avec un exemple plus structuré :créer un publipostage.

Un publipostage utilise deux fichiers, un (appelé dans cet exemple email_template.txt ) contenant un modèle d'e-mail que vous souhaitez envoyer :

De :Comité du programme 
À :{firstname} {lastname} <{email}>
Objet :Votre proposition de présentation

Cher { firstname},

Merci pour votre proposition de présentation :
  {title}

Nous avons le plaisir de vous informer que votre proposition a été acceptée ! Nous
vous contacterons sous peu avec de plus amples informations sur le
horaire de l'événement.

Merci,
Le Comité du Programme

Et l'autre est un fichier CSV (appelé proposals.csv ) avec les personnes à qui vous souhaitez envoyer l'e-mail :

firstname,lastname,email,title
Harry,Potter,[email protected],"Vaincre ton ennemi juré en 3 étapes faciles"
Jack,Reacher,[email protected],"Hand- combat à mains nues pour les débutants"
Mickey,Mouse,[email protected],"Survivre à la prise de parole en public avec une voix grinçante"
Santa,Claus,[email protected],"Élaboration efficace de listes"

Vous voulez lire le fichier CSV, remplacer les champs pertinents dans le premier fichier (en sautant la première ligne), puis écrire le résultat dans un fichier appelé acceptanceN.txt , en incrémentant N pour chaque ligne que vous analysez.

Écrivez le programme awk dans un fichier nommé mail_merge.awk . Les déclarations sont séparées par  ; dans les scripts awk. La première tâche consiste à définir la variable de séparation de champ et quelques autres variables dont le script a besoin. Vous devez également lire et supprimer la première ligne du CSV, sinon un fichier sera créé en commençant par Cher prénom . Pour ce faire, utilisez la fonction spéciale getline et remettre le compteur d'enregistrements à 0 après l'avoir lu.

BEGIN {
  FS=",";
  template="email_template.txt";
  output="acceptance";
  getline;
  NR=0;
}

La fonction principale est très simple :pour chaque ligne traitée, une variable est définie pour les différents champs :prénom , nom de famille , courriel , et titre . Le fichier modèle est lu ligne par ligne, et la fonction sub est utilisé pour remplacer toute occurrence des séquences de caractères spéciaux par la valeur de la variable correspondante. Ensuite, la ligne, avec toutes les substitutions effectuées, est sortie dans le fichier de sortie.

Étant donné que vous avez affaire au fichier de modèle et à un fichier de sortie différent pour chaque ligne, vous devez nettoyer et fermer les descripteurs de fichiers pour ces fichiers avant de traiter l'enregistrement suivant.

{
        # Lire les champs pertinents du fichier d'entrée
        firstname=$1;
        lastname=$2;
        email=$3;
        title=$4;

        # Définir le nom du fichier de sortie
        outfile=(output NR ".txt");

        # Lire une ligne du modèle, remplacer les champs spéciaux et
        # imprimer résultat dans le fichier de sortie
        while ( (getline ln 0 )
        {
                sub(/{firstname}/,firstname,ln);
                sub(/{lastname }/,nom,ln);
               sub(/{email}/,email,ln);
                sub(/{title}/,title,ln);
                print(ln)> outfile;
        }

        # Fermer le modèle et le fichier de sortie avant le prochain enregistrement
        close(outfile);
        close(template);
}

Vous avez terminé! Exécutez le script sur la ligne de commande avec :

awk -f mail_merge.awk proposals.csv 

ou

awk -f mail_merge.awk < proposals.csv 

et vous retrouverez les fichiers texte générés dans le répertoire courant.

Awk avancé :Nombre de mots fréquents

L'une des fonctionnalités les plus puissantes d'awk est le tableau associatif. Dans la plupart des langages de programmation, les entrées de tableau sont généralement indexées par un nombre, mais dans awk, les tableaux sont référencés par une chaîne de clés. Vous pouvez stocker une entrée du fichier proposals.txt de la section précédente. Par exemple, dans un seul tableau associatif, comme ceci :

        proposer["firstname"]=$1;
        proposer["lastname"]=$2;
        proposer["email"]=$3;
        proposer["title"]=$4;

Cela rend le traitement de texte très facile. Un programme simple qui utilise ce concept est l'idée d'un compteur de fréquence de mots. Vous pouvez analyser un fichier, décomposer les mots (en ignorant la ponctuation) dans chaque ligne, incrémenter le compteur pour chaque mot de la ligne, puis sortir les 20 premiers mots qui apparaissent dans le texte.

Tout d'abord, dans un fichier appelé wordcount.awk , définissez le séparateur de champs sur une expression régulière qui inclut des espaces et des signes de ponctuation :

BEGIN {
        # ignorer 1 ou plusieurs occurrences consécutives des caractères
        # dans le groupe de caractères ci-dessous
        FS="[ .,:;()<>{}@!\ "'\t]+" ;
}

Ensuite, la fonction de boucle principale itérera sur chaque champ, en ignorant les champs vides (ce qui se produit s'il y a de la ponctuation à la fin d'une ligne), et incrémentera le nombre de mots pour les mots de la ligne.

{
        for (i =1; i <=NF; i++) {
                if ($i !="") {
                        mots[$i]++ ;
                }
        }
}

Enfin, une fois le texte traité, utilisez la fonction END pour imprimer le contenu du tableau, puis utilisez la capacité de awk à diriger la sortie dans une commande shell pour effectuer un tri numérique et imprimer les 20 mots les plus fréquents :

END {
        sort_head ="sort -k2 -nr | head -n 20";
        for (word in words) {
                printf "%s\t%d\n" , mot, mots[mot] | sort_head ;
        }
        close (sort_head) ;
}

L'exécution de ce script sur une version antérieure de cet article a produit cette sortie :

[[email protected]]$ awk -f wordcount.awk le     79
awk     41
a       39
et     33
sur     32
dans     27
à     26
est      25
ligne    23
pour     23
va      22
fichier 21
nous      16
Nous      15
avec    12
qui   12
par     12
cette      11
sortie  11
fonction        11

Quelle est la prochaine ?

Plus de ressources Linux

  • Aide-mémoire des commandes Linux
  • Aide-mémoire des commandes Linux avancées
  • Cours en ligne gratuit :Présentation technique de RHEL
  • Aide-mémoire sur le réseau Linux
  • Aide-mémoire SELinux
  • Aide-mémoire sur les commandes courantes de Linux
  • Que sont les conteneurs Linux ?
  • Nos derniers articles Linux

Si vous voulez en savoir plus sur la programmation awk, je vous recommande vivement le livre Sed and awk par Dale Dougherty et Arnold Robbins.

L'une des clés pour progresser dans la programmation awk est de maîtriser les "expressions régulières étendues". Awk propose plusieurs ajouts puissants à la syntaxe d'expression régulière sed que vous connaissez peut-être déjà.

Une autre excellente ressource pour apprendre awk est le guide de l'utilisateur GNU awk. Il contient une référence complète pour la bibliothèque de fonctions intégrée d'awk, ainsi que de nombreux exemples de scripts awk simples et complexes.


Linux
  1. Sécurisez vos conteneurs avec SELinux

  2. Analysez votre sécurité Linux avec Lynis

  3. 10 tutoriels pour affiner vos compétences en ligne de commande

  4. Linux - Comment synchroniser deux dossiers avec des outils de ligne de commande ?

  5. Fusionner deux fichiers ligne par ligne avec le symbole délimiteur Triple Pipe "|||" ?

Épicez votre bureau Linux avec Cinnamon

Commande AWK sous Linux avec des exemples

Guide facile pour surveiller vos systèmes avec Checkmk

Testez vos compétences BASH en jouant à des jeux en ligne de commande

Gérer le saut de ligne avec les commandes Fold et FMT dans le terminal Linux

10 tutoriels Vim pour démarrer vos compétences d'éditeur