GNU/Linux >> Tutoriels Linux >  >> Linux

Premiers pas avec les expressions régulières :un exemple

Dans Présentation des expressions régulières , j'ai couvert ce qu'ils sont et pourquoi ils sont utiles. Maintenant, nous avons besoin d'un exemple concret à utiliser comme outil d'apprentissage. En voici un que j'ai rencontré il y a plusieurs années.

Cet exemple met en évidence la puissance et la flexibilité de la ligne de commande Linux, en particulier les expressions régulières, pour leur capacité à automatiser les tâches courantes. J'ai administré plusieurs listes de diffusion au cours de ma carrière et je le fais toujours. Les gens m'envoient des adresses e-mail à ajouter à ces listes. Dans plusieurs cas, j'ai reçu une liste de noms et d'adresses e-mail au format Microsoft Word à ajouter à l'une des listes.

La liste gênante

La liste elle-même n'était pas très longue, mais elle était incohérente dans sa mise en forme. Une version abrégée de cette liste, avec les changements de nom et de domaine, est affichée ici :

Team 1	Apr 3 
Leader  Virginia Jones  [email protected]	
Frank Brown  [email protected]	
Cindy Williams  [email protected]	
Marge smith   [email protected] 
 [Fred Mack]   [email protected]	

Team 2	March 14
leader  Alice Wonder  [email protected]	
John broth  [email protected]	
Ray Clarkson  [email protected]	
Kim West    [email protected]	
[JoAnne Blank]  [email protected]	

Team 3	Apr 1 
Leader  Steve Jones  [email protected]	
Bullwinkle Moose [email protected]	
Rocket Squirrel [email protected]	
Julie Lisbon  [email protected]	
[Mary Lastware) [email protected]

La liste d'origine contenait des lignes supplémentaires, des caractères comme les crochets et les parenthèses qui doivent être supprimés, des espaces comme les espaces et les tabulations, et quelques lignes vides. Le format requis pour ajouter ces e-mails à la liste est <first> <last> <[email protected]> . Notre tâche est de transformer cette liste dans un format utilisable par le logiciel de liste de diffusion.

Il était évident que j'avais besoin de manipuler les données afin de les transformer en un format acceptable pour l'entrée dans la liste. Il est possible d'utiliser un éditeur de texte ou un traitement de texte tel que LibreOffice Writer pour apporter les modifications nécessaires à ce petit fichier. Cependant, les gens m'envoient assez souvent des fichiers comme celui-ci, donc cela devient une corvée d'utiliser un traitement de texte pour effectuer ces modifications. Malgré le fait que Writer dispose d'une bonne fonction de recherche et de remplacement, chaque caractère ou chaîne doit être remplacé individuellement, et il n'y a aucun moyen de sauvegarder les recherches précédentes.

Writer possède une fonctionnalité de macro puissante, mais je ne connais aucun de ses deux langages :LibreOffice Basic ou Python. Je connais la programmation shell Bash.

J'ai fait ce qui vient naturellement à un administrateur système :j'ai automatisé la tâche. La première chose que j'ai faite a été de copier les données d'adresse dans un fichier texte afin de pouvoir travailler dessus à l'aide d'outils de ligne de commande. Après quelques minutes de travail, j'ai développé le programme en ligne de commande Bash présenté dans l'article précédent :

$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/\]//g" -e "s/)//g" | awk '{print $1" "$2" <"$3">"}' > addresses.txt

Ce code a produit la sortie souhaitée sous la forme du fichier addresses.txt . J'ai utilisé mon approche habituelle pour écrire des programmes en ligne de commande comme celui-ci en créant le pipeline une commande à la fois.

Décomposons ce pipeline en ses composants pour voir comment il fonctionne et s'intègre. Toutes les expériences de cette série doivent être effectuées en tant qu'utilisateur non privilégié. J'ai également fait cela sur une machine virtuelle que j'ai créée pour les tests :studentvm1 .

L'exemple de fichier

Tout d'abord, nous devons créer le fichier d'exemple. Créez un répertoire nommé testing sur votre ordinateur local, puis copiez le texte ci-dessous dans un nouveau fichier texte nommé Experiment_6-1.txt , qui contient les trois entrées d'équipe présentées ci-dessus.

Team 1  Apr 3 
Leader  Virginia Jones  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  

Team 2  March 14
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]

Team 3  Apr 1 
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]

Suppression des lignes inutiles avec grep

Les premières choses que je vois qui peuvent être faites sont quelques-unes des plus faciles. Étant donné que les noms d'équipe et les dates sont sur des lignes par eux-mêmes, nous pouvons utiliser ce qui suit pour supprimer les lignes contenant le mot "Équipe :"

[student@studentvm1 testing]$  cat Experiment_6-1.txt | grep -v Team

Je ne reproduirai pas les résultats de chaque étape de la construction de ce programme Bash, mais vous devriez pouvoir voir les changements dans le flux de données tel qu'il apparaît sur STDOUT, la session terminale. Nous ne l'enregistrerons pas dans un fichier avant la fin.

Dans cette première étape de transformation du flux de données en un flux utilisable, nous utilisons le grep commande avec un modèle littéral simple, Team . Les littéraux sont le type de modèle le plus basique que nous pouvons utiliser comme expression régulière, car il n'y a qu'une seule correspondance possible dans le flux de données recherché, et c'est la chaîne Team .

Nous devons supprimer les lignes vides afin de pouvoir utiliser un autre grep déclaration pour les éliminer. Je trouve qu'en joignant l'expression régulière pour le deuxième grep la commande entre guillemets garantit qu'elle est correctement interprétée :

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$"
Leader  Virginia Jones  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]
[Mary Lastware) [email protected]
[student@studentvm1 testing]$

L'expression "^\s*$" illustre les ancres et utilise la barre oblique inverse (\) comme caractère d'échappement pour changer la signification d'un "s" littéral (dans ce cas) en un métacaractère qui désigne tout espace blanc tel que des espaces, des tabulations ou d'autres caractères non imprimables. Nous ne pouvons pas voir ces caractères dans le fichier, mais il en contient certains.

L'astérisque, alias splat (*), spécifie que nous devons faire correspondre zéro ou plusieurs des caractères d'espacement. Cet ajout correspondrait à plusieurs tabulations, plusieurs espaces ou toute combinaison de ceux-ci dans une ligne autrement vide.

Afficher des espaces blancs supplémentaires avec Vim

Ensuite, j'ai configuré mon éditeur Vim pour afficher les espaces en utilisant des caractères visibles. Pour ce faire, ajoutez la ligne suivante à votre propre ~.vimrc ou au fichier global /etc/vimrc fichier de configuration :

set listchars=eol:$,nbsp:_,tab:<->,trail:~,extends:>,space:+

Ensuite, démarrez ou redémarrez Vim.

J'ai trouvé beaucoup d'informations mauvaises, incomplètes et contradictoires sur Internet dans mes recherches sur la façon de procéder. L'aide intégrée de Vim contient les meilleures informations, et la ligne de données que j'ai créée à partir de celle ci-dessus est celle qui fonctionne pour moi.

Remarque : Dans l'exemple ci-dessous, les espaces réguliers sont affichés sous la forme +; les onglets sont affichés sous la forme < , <> , ou <–> , et remplissez la longueur de l'espace couvert par l'onglet. Le caractère de fin de ligne (EOL) est affiché sous la forme $ .

Le résultat, avant toute opération sur le fichier, est affiché ici :

Team+1<>Apr+3~$
[email protected]<-->$
[email protected]<---->$
[email protected]<--->$
[email protected]~$
+[Fred+Mack][email protected]<>$
$
Team+2<>March+14$
[email protected]<----->$
[email protected]<>$
[email protected]<-->$
[email protected]>$
[JoAnne+Blank][email protected]<---->$
$
Team+3<>Apr+1~$
[email protected]<-->$
[email protected]<--->$
[email protected]<>$
[email protected]<------>$
[Mary+Lastware)[email protected]$

Suppression des caractères inutiles avec sed

Vous pouvez voir qu'il y a beaucoup de caractères d'espacement qui doivent être supprimés de notre fichier. Nous devons également nous débarrasser du mot "leader", qui apparaît deux fois et dont la majuscule est une fois. Débarrassons-nous d'abord du "leader". Cette fois, nous utiliserons sed (éditeur de flux) pour effectuer cette tâche en substituant une nouvelle chaîne (ou une chaîne nulle dans notre cas) au modèle auquel elle correspond.

Ajout de sed -e "s/[Ll]eader//" au pipeline fait ceci :

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//"

Dans ce sed commande, -e signifie que l'expression entre guillemets est un script qui produit un résultat souhaité. Dans l'expression, les s signifie qu'il s'agit d'une substitution. La forme de base d'une substitution est s/<regex>/<replacement string>/ , donc /[Ll]eader/ est notre chaîne de recherche.

L'ensemble [Ll] correspond à L ou l , donc [Ll]eader correspond à leader ou Leader . Dans ce cas, la chaîne de remplacement est nulle car elle ressemble à une double barre oblique sans caractère ni espace entre les deux barres obliques (// ).

Débarrassons-nous également de certains des caractères superflus comme []() cela ne sera pas nécessaire :

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g"

Nous avons ajouté quatre nouvelles expressions au sed déclaration. Chacun supprime un seul caractère. La première de ces expressions supplémentaires est un peu différente, car l'accolade gauche ([ ) peut marquer le début d'un ensemble. Nous devons échapper l'accolade pour nous assurer que sed l'interprète correctement comme un caractère normal et non spécial.

Faire du rangement avec awk

Nous pourrions utiliser sed pour supprimer les espaces de début de certaines lignes, mais le awk commande peut le faire, réorganisez les champs si nécessaire et ajoutez le <> caractères autour de l'adresse e-mail :

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g" | awk '{print $1" "$2" <"$3">"}'

Le awk L'utilitaire est en fait un langage de programmation puissant qui peut accepter des flux de données sur son STDIN. Ce fait le rend extrêmement utile dans les programmes et les scripts en ligne de commande.

Le awk L'utilitaire fonctionne sur les champs de données et le séparateur de champ par défaut est un espace, c'est-à-dire n'importe quelle quantité d'espace blanc. Le flux de données que nous avons créé jusqu'à présent comporte trois champs séparés par des espaces (<first> , <last> , et <email> ):

awk '{print $1" "$2" <"$3">"}'

Ce petit programme prend chacun des trois champs ($1 , $2 , et $3 ) et les extrait sans espace de début ou de fin. Il les imprime ensuite dans l'ordre, en ajoutant un seul espace entre chacun ainsi que le <> caractères nécessaires pour entourer l'adresse e-mail.

Conclusion

La dernière étape ici serait de rediriger le flux de données de sortie vers un fichier, mais c'est trivial, donc je vous laisse le soin d'effectuer cette étape. Il n'est pas vraiment nécessaire que vous le fassiez.

J'ai enregistré le programme Bash dans un fichier exécutable, et maintenant je peux exécuter ce programme chaque fois que je reçois une nouvelle liste. Certaines de ces listes sont assez courtes, comme celle de cet exemple. D'autres ont été assez longs, contenant parfois jusqu'à plusieurs centaines d'adresses et de nombreuses lignes de "trucs" qui ne contiennent pas d'adresses à ajouter à la liste.

Remarque : Cet article est une version légèrement modifiée du chapitre 6 du volume 2 de mon livre Linux, Utiliser et administrer Linux :de zéro à SysAdmin, qui doit sortir d'Apress fin 2019.


Linux
  1. Premiers pas avec Zsh

  2. Démarrer avec ls

  3. Premiers pas avec Samba pour l'interopérabilité

  4. Premiers pas avec PostgreSQL sous Linux

  5. Premiers pas avec SSH sous Linux

Premiers pas avec GitHub

Premiers pas avec le gestionnaire de paquets Nix

Premiers pas avec systemctl

Premiers pas avec cPanel

Premiers pas avec SiteApps

Premiers pas avec la commande Tar