DEV Community

chris
chris

Posted on • Edited on

La ligne de commande Linux pour les impatient.e.s (2) : cas pratique

Avant de commencer : Il est possible que lorsqu'on lance une commande, on se trompe, souvent même d'ailleurs et moi le premier. Cependant, il existe une commande magique qui permet d'interrompre le processus en cours : CTRL+C. Il vous suffira d'appuyer sur la touche "contrôle" en même temps que "c" et le processus en cours sera interrompu immédiatement. On stoppe, on corrige et on recommence !

Cut

Dans l'article précédent, nous avons pu voir comment gérer des listes à colonne unique avec grep. Maintenant qu'en est-il des cas où les lignes sont un peu plus denses d'informations ?

Il existe un outil simple : cut qui nous permettra de régler une grande partie de nos soucis.

Prenons un format comme le csv et l'exemple suivant:

Robert;Dupont;rue du Verger, 12;
"Michel";"Durand";" av. de la Ferme, 89 ";
"Michel ""Michele""";"Durand";" av. de la Ferme, 89";
"Michel;Michele";"Durand";"av. de la Ferme, 89";
Enter fullscreen mode Exit fullscreen mode

Sauvons le directement dans un fichier avec la commande suivante :

echo 'Robert;Dupont;rue du Verger, 12;
"Michel";"Durand";" av. de la Ferme, 89 ";
"Michel ""Michele""";"Durand";" av. de la Ferme, 89";
"Michel;Michele";"Durand";"av. de la Ferme, 89";
' > exemple.csv
Enter fullscreen mode Exit fullscreen mode

echo renvoie l'information que vous lui donner à l'instar d'un écho. Donc ici, echo enverra les informations que nous avons copiées et collées depuis la page Wikipédia. Ensuite le chevron simple (>) créera et remplira un nouveau fichier exemple.csv avec les informations que nous lui envoyons.

Astuce : le copier coller dans le terminal fonctionne dès fois différemment en fonction des configurations. Vous pouvez coller en appuyant sur la touche majuscule en même temps que "contrôle" et "v" ou bien, en faisant clic droit et en choisissant l'option "coller".

Vérifions que le fichier n'est pas vide avec cat exemple.csv. Si tout va bien, les informations que nous avons collées s'y trouvent.

cut fonctionne avec deux options principales : -d pour définir le délimiteur et -f pour choisir la colonne que vous voulez récupérer.

Pour un premier essai, essayons : cut -d " " -f 1. Ici nous définissions une espace comme délimiteur et prenons le premier résultat après ce délimiteur.

cat exemple.csv | cut -d " " -f 1
Enter fullscreen mode Exit fullscreen mode

Donne comme résultat :

Robert;Dupont;rue
"Michel";"Durand";"
"Michel
"Michel;Michele";"Durand";"av.
Enter fullscreen mode Exit fullscreen mode

Tout s'est bien passé ! Ce sont tous les premiers résultats de la première colonne avant une espace.

Expérimentez avec d'autres délimiteurs comme ";", "," ou "." et d'autre choix de colonnes (vous pouvez sélectionner plusieurs colonnes comme ceci : -f 1,2), qu'observez-vous ?

Sed

Il est possible que vous ayez à modifier les données de votre colonne. Travailler avec les données, c'est souvent un peu de code et beaucoup de nettoyage. sed est une commande qui va vous permettre à remplacer des caractères selon une condition. En gros, c'est comme le chercher remplacer de n'importe quel éditeur de texte mais ici, il sera possible de l’enchaîner à notre processus.

La syntaxe de sed fonctionne ainsi : sed mode/texte à changer/comment le texte doit être changé/option fichier. Donc pour notre objectif : sed 's/;/ /g'. Ici nous utilisons le mode s qui signifie substitution ; nous remplaçons les ";" par des espaces et nous utilisons l'option g ce qui signifie "global" ; c'est-à-dire que nous appliquons cette condition à toutes les occurrences du fichier (précision: à toutes les occurrences de la ligne).

Commençons par récupérer les informations depuis notre csv :

cat exemple.csv | cut -d " " -f 1
Enter fullscreen mode Exit fullscreen mode

Et remplaçons les ";" par une espace :

cat exemple.csv | cut -d " " -f 1 | sed 's/;/ /g'
Enter fullscreen mode Exit fullscreen mode

Résultat :

Robert Dupont rue
"Michel" "Durand" "
"Michel
"Michel Michele" "Durand" "av.
Enter fullscreen mode Exit fullscreen mode

Et voilà ! Rechercher, filtrer, remplacer !

Ici, nous utilisons sed enchaîné avec d'autres processus, si vous désirer l'utiliser seul avec un seul fichier, il faudra utiliser l'option -i. Exemple: sed s/brusselles/Bruxelles/g fichier -i. Cet exemple remplacera toutes les occurrences de "brusselles" dans le fichier "fichier" par son orthographe correcte : "Bruxelles".

Précision: l'option -i est utilisée pour sauvegarder la modification dans le même fichier, il est aussi possible de rediriger le résultat vers un autre fichier.

Variables

En programmation, les variables sont des emplacements dans lesquels on peut enregistrer des informations. Par défaut, le terminal Linux utilise un langage que l'on appelle Bash ou parfois appelé shell script.

Grâce à celui-ci, nous pouvons enregistrer des informations dans des variables et les réutiliser.

Pour définir une variable, choisissez un nom, ici "nombre_deux" et une valeur, ici "2". Assigner une valeur à une variable se fait via le signe "=" : nombre_deux=2 et puis appuyez sur Entrée. Ensuite pour l'appeler, il faudra toujours précéder la variable par le symbole $. Exemple : echo $variable_deux et votre terminal devra vous répondre "2".

Exemple complet:

nombre_deux=2
echo $nombre_deux
Enter fullscreen mode Exit fullscreen mode

Il est aussi possible de réassigner une variable:

nombre_deux=3
echo $nombre_deux
Enter fullscreen mode Exit fullscreen mode

Le résultat ici devra être "3".

Boucles

Voici un autre concept de programmation : les boucles. Les boucles permettent à un programme d'être exécuté en répétition jusqu'à arriver à une certain condition. La syntaxe de base sera comme suit :

for VARIABLE in LISTE; do ACTION $VARIABLE; done
Enter fullscreen mode Exit fullscreen mode

Pour lire ça en français, ça sera : "pour la variable "VARIABLE" dans la liste "LISTE", faire l'action "ACTION" et, quand il n'y a plus de variable dans la liste, terminer la boucle ("done" - réalisé, en français). Vous remarquerez que la variable est appelée avec le symbole "$" comme nous avons vu plus haut et que chaque instruction est séparée par un ";".

Vous ne devez pas nécessairement écrire les variables en capitales, je le fais juste pour différencier ce qui tient de la syntaxe de la fonction et ce que vous pouvez changer.

Essayons d'imprimer toutes les lignes de notre csv :

for ligne in $(cat exemple.csv); do echo $ligne; done
Enter fullscreen mode Exit fullscreen mode

Qu'est-ce $(cat exemple.csv) ? En utilisant $(), nous pouvons exécuter une autre fonction Bash à l'intérieur d'une fonction, un peu comme des poupées russes. Donc en faisant cat exemple.csv, nous avons imprimé le csv dans le terminal et ensuite commencé la boucle.

Devra donner ce résultat :

Robert;Dupont;rue
du
Verger,
12;…
"Michel";"Durand";"
av.
de
la
Ferme,
89
";…
"Michel
""Michele""";"Durand";"
av.
de
la
Ferme,
89";…
"Michel;Michele";"Durand";"av.
de
la
Ferme,
89";…
Enter fullscreen mode Exit fullscreen mode

Assez intéressant que le système coupe les lignes aux espaces...

Il est aussi possible de faire des boucles plus proches de ce qu'on retrouve dans les cours de maths, comme par exemple: "somme de tout n, partant de 0 jusque 100". En Bash (donc dans notre terminal), il sera possible de faire ça de la manière suivante (et en une ligne) :

somme=0; for i in $(seq 0 100); do somme=$(expr $somme + $i); done; echo $somme
Enter fullscreen mode Exit fullscreen mode

Alt Text

Ok, perdu.e.s ? La première fois, moi aussi. Revenons dessus pas à pas :

  • somme=0 : nous définissons une variable "somme" et l'initialisons à 0
  • ; : ce caractère nous permet de séparer différentes instructions en Bash. C'est-à-dire que nous disons à notre terminal de suivre la première instruction avec la suivante. Cela diffère de la barre verticale | où les deux instructions sont connectées.
  • for VARIABLE in CONDITION; do ACTION SUR VARIABLE; done : ceci est la syntaxe de base d'une boucle en Bash.
  • $(seq 0 100) : seq 0 100 est une instruction affichera les chiffres de 0 à 100 dans votre terminal (essayez !).
  • expr $somme + $i : pour que votre terminal comprenne que vous voulez faire une expression arithmétique, il faudra ajouter la fonction expr. Ensuite, appeler les deux variables somme et i (que nous avons définies au début de notre boucle) avec $. Cette fonction fera la somme de $somme ainsi que de $i et enregistra le résultat dans la variable somme.
  • done : permet de finir la boucle ouverte via for
  • echo $somme: va afficher le résultat final de notre boucle.

Félicitations, vous venez de faire votre première boucle !

Précisions: Pour seq, il est aussi possible de faire {1..100} et arriver au même résultat. Pour expr, il es aussi possible de faire $((1 + 1)).

Cas pratique : Fouiller une page web

Faire des additions, c'est utile mais nous avons tou.te.es des calculettes dans nos poches et franchement, on s'en fiche un peu de faire ça via le terminal.

Alors, voici un cas pratique qui va reprendre l'entièreté de la matière cet article et du précédent dans quelque chose d'utile : récupérer des informations d'une page web.

Ici, nous allons utiliser la plupart de concepts vus dans les deux premiers articles, s'il y a des parties que vous trouvez compliquées ou peu claires, n'hésitez pas à revenir sur vos pas. Le but n'est pas de tout comprendre d'un coup tout de suite mais d'intégrer les concepts à son aise.

D'abord, prenons cette page web : https://fr.wikipedia.org/wiki/Hedy_Lamarr.

Téléchargeons la via wget :

wget https://en.wikipedia.org/wiki/Hedy_Lamarr -O page.html
Enter fullscreen mode Exit fullscreen mode

L'option de destination du fichier est un "o" majuscule pas un zéro !

Vérifions la page :

head page.html
Enter fullscreen mode Exit fullscreen mode

En HTML, le langage de formatage des pages web, le liens sont précédés de la balise href= :

grep "href=" page.html
Enter fullscreen mode Exit fullscreen mode

Choisissons maintenant un délimiteur :

cut -d '"' -f 1
Enter fullscreen mode Exit fullscreen mode

Il est possible de faire passer plusieurs cut l'un à la suite de l'autre afin de filtrer au maximum le résultat de la page. En effet, le travail de filtrage de pages web peut être un peu laborieux au début afin de trouver les bons filtres. C'est important de tester différentes choses et de regarder le résultat et d'incrémenter progressivement la précision des-dits filtres.

Ici, nous allons récupérer tous les liens internes de la page Wikipédia, c'est-à-dire les liens qui commencent par /wiki/. Nous allons utiliser l'option -e de grep qui nous permettra de faire passer un filtre spécial (une expression régulière ou regex).

Les regex sont une langage de programmation qui permet de faire du filtrage plus précis de texte. Ce n'est pas le sujet de cet article car c'est assez abscon au début. Retenez ici jusque le "^" défini le début d'une chaine de caractère. Donc, dans l'exemple suivant ^/wiki/ signifie : toutes les lignes qui commencent exclusivement par "/wiki/".

grep "href=" page.html | cut -d '"' -f 2 | grep -e "^/wiki/" | sort -u > liens.txt
Enter fullscreen mode Exit fullscreen mode

Alt Text

Vous remarquerez que les liens ne sont pas complets, c'est pour cela que nous allons corriger cela avec sed et l'option -i :

sed 's/\/wiki\//https:\/\/fr\.wikipedia\.org\/wiki\//g' liens.txt -i
Enter fullscreen mode Exit fullscreen mode

Pourquoi des \ devant les caractères spéciaux ? Car sed fonctionne avec des regex et chaque caractère à une signification et une fonction particulière. Nous voulons considérer ces caractères de façon littérale, donc nous devons les échapper avec le caractère \. C'est-à-dire, dire à sed qu'il ne faut pas les considérer comme des fonctions mais comme de simples caractères. C'est le cas pour les / et .. Si vous regardez bien, les / qui se sont pas échappés, ce sont ceux qui sont nécessaires pour la syntaxe de sed.
Astuce : Il est aussi possible d'utiliser # lorsqu'il y a beaucoup de caractères à échapper. Donc, ceci est valide aussi et donnera le même résultat : sed 's#/wiki//#https://fr.wikipedia/.org/wiki/#' liens.txt -i (et est un peu plus facile à lire).

Vérifions notre liste de liens :

head liens.txt
Enter fullscreen mode Exit fullscreen mode

Maintenant, nous allons télécharger tous les liens les uns à la suite de l'autre pour une lecture hors-ligne confortable.

mkdir dossier_liens
for lien in $(cat liens.txt); do wget $lien -P dossier_liens; done
Enter fullscreen mode Exit fullscreen mode

L'option -P permet d'envoyer le résultat de wget dans un dossier plutôt que dans un fichier.

Et voilà le travail !

Il est possible de faire tout cela en une seule ligne. Les fameux "one-liners" dont les développeur.euse.s raffolent tant. Essayer de trouver une manière de faire ces commandes en une seule ligne et lancez-la ! Essayez d'arriver au même résultat avec différentes pages Wikipédia.

Conclusion

Nous avons vu dans ces deux articles comment traiter des listes, les filtrer, les nettoyer et en refaire des objets que nous pouvons utiliser par la suite !

N'hésitez pas à me contacter si vous avez des questions ou des remarques.

Edit : Merci à Dattaz pour les précisions et les astuces !

Top comments (1)

Collapse
 
teamdevops profile image
teamdevops

Contenu hyper détaillé et clair. Merci