6 utilisations de filtrage de texte pour la commande awk sous Linux
Liens rapides
- Faire correspondre le texte en utilisant des expressions régulières
- Sélectionner les lignes par numéro de ligne, longueur, nombre de champs ou dernier champ
- Comparer et filtrer les valeurs des champs numériques
- Capturer les plages de lignes entre des motifs correspondants
- Exclure les entrées indésirables ou en double
- Reformater le texte en choisissant des colonnes spécifiques
La commande awk est un outil polyvalent de traitement de texte sous Linux. Elle filtre et manipule les fichiers en utilisant des motifs, des conditions et des actions. Elle prend en charge un large éventail de scénarios, ce qui la rend simple pour extraire des données spécifiques à partir des journaux, des fichiers de configuration ou de tout fichier texte.
Voici quelques façons courantes de filtrer du texte avec awk. Elles incluent les recherches par expressions régulières, la sélection de lignes et de champs, le filtrage numérique, et plus encore.
Faire correspondre le texte en utilisant des expressions régulières
Bien que les expressions régulières aient une courbe d'apprentissage réputée escarpée, elles sont le couteau suisse de la manipulation de texte. Lorsqu'on les utilise avec des outils comme awk, on peut rechercher des motifs, du plus simple au plus complexe, à travers des fichiers entiers en quelques millisecondes.
Commençons par la syntaxe de base :
awk '/pattern/ {print}' filename`Les barres obliques indiquent à awk que vous utilisez une expression régulière, et les accolades contiennent l'action à effectuer sur une correspondance. Par exemple, vous pouvez imprimer toutes les entrées du journal contenant « error » à partir d'un fichier journal avec ceci :
awk '/error/ {print}' syslog.logCette ligne de commande capture chaque ligne contenant le mot 'error', mais les expressions régulières vous permettent d'aller plus loin. Par exemple, pour trouver les lignes commençant par INFO ou WARN, utilisez cette commande :
awk '/^(INFO|WARN)/ {print}' syslog.logIci, le pipe | agit comme un opérateur OU, et le caret ^correspond au début d'une ligne.
Ce que j'aime dans les expressions régulières, c'est qu'elles vont au-delà des mots exacts, vous permettant d'utiliser des caractères génériques pour des recherches plus complexes. Par exemple, vous pouvez trouver des adresses e-mail dans un fichier texte avec ce modèle :
awk '/[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+/ {print}' contacts.txtCe modèle correspond à des séquences de lettres et de chiffres, suivies d'un symbole @, de nouvelles lettres et chiffres, d'un point, et enfin de nouvelles lettres. Bien qu'il ne soit pas parfait pour tous les formats d'adresse e-mail, il permet de détecter la plupart des cas courants.
Vous pouvez également utiliser l'opérateur tilde (~) pour un rapprochement plus précis dans des champs spécifiques. Cette approche est très efficace pour les données structurées. Par exemple, si vous souhaitez rechercher uniquement ERROR dans le troisième champ de chaque ligne, vous pouvez utiliser ceci :
awk '$3 ~ /ERROR/ {print}' system.logCette approche la rend plus précise que de rechercher la ligne entière. De plus, si la sensibilité à la casse pose problème, utilisez simplement la fonction tolower() comme ceci :
awk 'tolower($0) ~ /error/ {print}' mixed_case.logCette commande convertit chaque ligne en minuscules avant de rechercher, ce qui lui permet de trouver ERROR, Error, error et toute autre variation de majuscules et minuscules.
Sélectionner les lignes par numéro de ligne, longueur, nombre de champs ou dernier champ
Parfois, vous avez besoin de lignes spécifiques en fonction de leur position ou de leurs caractéristiques, et non de leur contenu. awk gère ces scénarios de manière excellente grâce à ses variables intégrées qui permettent de filtrer les lignes par position ou structure. Ces variables intégrées incluent NR, length(), NF et $NF.
Commençons par la variable NR. Elle signifie Number of Record (ou simplement numéro de ligne). awk l'incrémente pour chaque ligne qu'il lit. Vous pouvez l'utiliser pour récupérer des lignes spécifiques ou des plages de lignes.
Pour afficher les 10 premières lignes d'un fichier, utilisez :
awk 'NR <=10 {print}' largefile.txt
De même, pour obtenir toutes les lignes numérotées de manière paire, utilisez 2 :
awk 'NR % 2 == 0 {print}' file.txt
Pour les plages, vous pouvez combiner plusieurs conditions NR avec l'opérateur &&, comme ceci :
awk 'NR >= 50 && NR <= 100 {print}' file.txt
Cela imprime les lignes 50 à 100. Vous pouvez également combiner la fonction length() avec awk lorsque vous traitez des fichiers ayant un formatage incohérent ou lorsque vous souhaitez filtrer les lignes vides.
Par exemple, pour compter les caractères avec la fonction length() et afficher ensuite uniquement les lignes de plus de 80 caractères, utilisez :
awk 'length($0) > 80 {print}' code.py
Maintenant, parlons d'une autre variable couramment utilisée, NF, qui fait référence au nombre de champs. En utilisant cette variable, awk divise automatiquement chaque ligne en champs en fonction d'un délimiteur (par défaut, espaces ou tabulations).
Par exemple, pour les fichiers CSV ou les données structurées, vous pouvez utiliser la variable NF pour compter les champs (colonnes). Vous pouvez filtrer en fonction du nombre de champs que contient chaque ligne :
awk 'NF == 5 {print}' customer_data.csvCela ne conserve que les lignes comportant exactement 5 champs, ce qui vous aide à repérer les enregistrements incomplets. Pour faire le contraire, et n'imprimer que les lignes qui n'ont pas exactement 5 champs, utilisez l'opérateur != au lieu de ==. De plus, pour imprimer les lignes comportant au moins 5 champs (colonnes), utilisez l'opérateur >=.
Alors que NF vous indique combien de champs il y a, $NF vous donne la valeur du tout dernier champ. La variable $NF représente le dernier champ de chaque ligne, quel que soit le nombre de champs. Cela est extrêmement utile lorsqu'on manipule des fichiers dont le nombre de colonnes varie.
Prenez cette commande :
awk '$NF == "COMPLETED" {print}' task_list.txtCela trouve toutes les lignes se terminant par COMPLETED, même si certaines lignes ont 3 champs et d'autres en ont 7.
Vous pouvez également combiner toutes ces conditions ensemble :
awk 'length($0) > 50 && NF >= 4 {print}' mixed_data.txtCette commande n'affiche que les lignes dépassant 50 caractères et contenant au moins 4 champs. Elle garantit que la sortie exclut les lignes courtes ou incomplètes.
Comparer et filtrer les valeurs des champs numériques
awk est assez intelligent pour traiter les champs contenant des nombres comme de véritables nombres, et pas seulement comme du texte. Cela signifie que vous pouvez effectuer des comparaisons mathématiques sans aucune fonction de conversion spéciale, ouvrant ainsi tout un nouveau monde de possibilités de filtrage.
Maintenant, disons que vous avez un fichier CSV des scores des étudiants, et que vous voulez ne retourner que les étudiants ayant obtenu plus de 80 points. Vous pouvez faire cela avec :
awk -F, '$2 > 80 {print $1, $2}' scores.csvIci, nous utilisons -F, pour indiquer à awk que les champs sont séparés par des virgules. $2 fait référence au deuxième champ ou colonne (le score) et $1 est le nom.
Lorsqu'on travaille avec des fichiers texte, les pourcentages peuvent poser des problèmes si le symbole % est inclus dans un champ. Vous pouvez le supprimer avec gsub() :
awk '{gsub(/%/, "", $4); if($4 > 75) print}' performance.txtCette commande supprime le symbole % du quatrième champ, puis vérifie si le nombre restant dépasse 75.
Vous pouvez également utiliser plusieurs conditions avec des opérateurs logiques. Par exemple, si vous souhaitez extraire des valeurs de ventes d'un fichier CSV comprises entre 500 $et 2000 $, exécutez :
awk -F, '$3 > 500 && $3 < 2000 {print}' sales.csv
Vous pouvez également combiner des conditions avec l'opérateur || (OU). Par exemple, pour trouver des enregistrements où les ventes sont très élevées ou très faibles, utilisez :
awk -F, '$3 > 5000 || $3 < 100 {print}' sales.csv
Au-delà des comparaisons numériques, vous pouvez également utiliser plusieurs conditions pour rechercher un texte spécifique, vérifier des dates ou exclure des enregistrements indésirables.
Vous pouvez également combiner && et ||. Cependant, les parenthèses sont essentielles pour contrôler correctement la logique. Supposons que vous souhaitiez trouver des comptes qui sont soit ACTIFS, soit EN ATTENTE, mais seulement si leur solde dépasse 1000 $. Vous écririez :
awk -F, '($2 == "ACTIVE" || $2 == "PENDING") && $3 > 1000' accounts.csvSans parenthèses, la priorité des opérateurs changerait le sens du filtre.
Capturer les plages de lignes entre des motifs correspondants
La plupart des utilisateurs de Linux connaissent l'utilisation de grep pour capturer des informations spécifiques. Cependant, awk peut également sélectionner une plage de lignes, en commençant par une ligne correspondant à un start_pattern et en terminant par une ligne correspondant à un end_pattern.
La syntaxe est élégamment simple :
awk '/start_pattern/,/end_pattern/' filenameCela capture la ligne de début, toutes les lignes intermédiaires et la ligne de fin. Si vous souhaitez exclure les marqueurs eux-mêmes, vous pouvez utiliser une approche basée sur des indicateurs comme celle-ci :
awk '/BEGIN/{flag=1; next} /END/{flag=0} flag' logfile.txtDe plus, nous pouvons également capturer des blocs d'erreurs complets qui commencent par un texte spécifié et se terminent à la ligne vide suivante.
awk '/ERROR:/,/^$/ {print}' application.logIci, awk commencera à imprimer les lignes lorsqu'il rencontrera une ligne contenant « ERREUR : » et continuera jusqu'à ce qu'il trouve la première ligne vide.
Exclure les entrées indésirables ou en double
Nettoyer les données signifie souvent supprimer ce que vous ne voulez pas. awk offre des moyens simples de filtrer le bruit et de supprimer les données redondantes.
L'opérateur NOT (!) est votre principal outil pour l'exclusion. Vous pouvez le placer avant n'importe quel motif ou condition pour inverser la correspondance, indiquant à awk d'effectuer une action sur toutes les lignes qui ne correspondent pas.
Par exemple, supposons que vous souhaitiez exclure tous les messages contenant DEBUG de votre fichier journal d'application. Utilisez ceci :
awk '!/DEBUG/' application.logCette commande affiche chaque ligne de application.log sauf si elle contient le mot DEBUG.
Vous pouvez également combiner cela avec des conditions basées sur les champs, par exemple, vous pouvez voir tout le trafic qui ne provient pas de votre adresse IP de surveillance interne.
awk '$1 != "10.0.0.5"' access.logDe même, une autre opération importante d'awk consiste à filtrer les commentaires (lignes commençant par #) et les lignes vides d'un fichier de configuration. Pour ce faire, utilisez :
awk '!/^#/ && NF > 0 {print}' config.iniCela ignore les lignes commençant par # et supprime également les lignes vides.
Vous pouvez également supprimer les doublons en fonction d'un champ spécifique. Par exemple, supposons que vous ayez un fichier CSV contact_list avec trois colonnes : ID, Nom et Email. Pour ne conserver que le premier enregistrement pour chaque adresse e-mail unique (dans le troisième champ), utilisez :
awk '!seen[$3]++ {print}' contact_list.csvDe plus, vous pouvez exclure les correspondances insensibles à la casse avec la fonction tolower() :
Reformater le texte en choisissant des colonnes spécifiques
Les données brutes arrivent souvent dans une structure dont vous n’avez pas vraiment besoin, et awk facilite leur réorganisation en quelque chose de plus utile. Vous pouvez sélectionner des colonnes spécifiques, changer leur ordre, ou même les combiner en de nouveaux champs.
Par exemple, si vous souhaitez uniquement imprimer la deuxième et la cinquième colonne d'un fichier, vous pouvez utiliser :
awk -F, '{print $2, $5}' sales.csvSi vous voulez changer l'ordre des colonnes, échangez $5 avec $2.
Par défaut, awk sépare la sortie par des espaces, mais vous pouvez insérer votre propre séparateur, comme un symbole de barre verticale.
awk '{print $1 "|" $3}' data.txtLorsqu'on travaille avec des fichiers CSV, la première ligne est souvent un en-tête. Vous pouvez l'ignorer avec NR > 1 et réorganiser les colonnes pour afficher l'email suivi du nom.
awk -F, 'NR > 1 {print $3, "->", $1, $2}' contacts.csvVous pouvez également combiner des champs pour en créer de nouveaux, comme joindre le prénom et le nom de famille pour obtenir un nom complet avant d'envoyer l'e-mail.
awk -F, '{print $1 " " $2, $3}' contacts.csvEnfin, si vous voulez que le résultat soit plus clair, vous pouvez ajouter votre propre en-tête avant les données en utilisant un bloc BEGIN.
awk 'BEGIN {print "Name,Email"} {print $1 "," $2}' data.txtCes exemples simples suffisent pour commencer à reformater le texte dans une mise en page qui correspond mieux à vos besoins.
Souvenez-vous, awk excelle dans le traitement de texte structuré, tout ce qui possède des motifs ou des séparations de champs cohérents. Plus votre format de données est régulier, plus awk devient puissant. Et lorsque vous combinez ces techniques de filtrage avec d'autres outils Linux via des pipes, vous créez des flux de traitement de texte extrêmement efficaces.





