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";
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
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
Donne comme résultat :
Robert;Dupont;rue
"Michel";"Durand";"
"Michel
"Michel;Michele";"Durand";"av.
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
Et remplaçons les ";" par une espace :
cat exemple.csv | cut -d " " -f 1 | sed 's/;/ /g'
Résultat :
Robert Dupont rue
"Michel" "Durand" "
"Michel
"Michel Michele" "Durand" "av.
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
Il est aussi possible de réassigner une variable:
nombre_deux=3
echo $nombre_deux
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
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
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 faisantcat 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";…
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
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 fonctionexpr
. Ensuite, appeler les deux variablessomme
eti
(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 variablesomme
. -
done
: permet de finir la boucle ouverte viafor
-
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. Pourexpr
, 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
L'option de destination du fichier est un "o" majuscule pas un zéro !
Vérifions la page :
head page.html
En HTML, le langage de formatage des pages web, le liens sont précédés de la balise href=
:
grep "href=" page.html
Choisissons maintenant un délimiteur :
cut -d '"' -f 1
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
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
Pourquoi des
\
devant les caractères spéciaux ? Carsed
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 desed
.
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
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
L'option
-P
permet d'envoyer le résultat dewget
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)
Contenu hyper détaillé et clair. Merci