MO101 - Introduction à Linux - Feuille TD2
Bienvenue dans le deuxième TD du cours MO101 !
Au cours de ce TD, nous allons appronfondir nos connaissances de la ligne de commande en appliquant les différents concepts vu plus tôt en amphithéâtre : la sélection de fichiers, la redirection, et la technique du tuyau.
Mais avant tout, vous devez répéter le tout premier exercice du TD précédent en récupérant cette archive et en désarchivant son contenu dans votre dossier "mo101" (et non directement dans le dossier personnel !):
Ensuite, ouvrez un terminal et rendez-vous dans le dossier "td2".
Partie 1 - Sélection de fichiers
Dans cette partie, nous allons mettre en pratique les méta-caractères permettant une sélection plus efficace d'ensembles de fichiers. Voici un rappel de ces caractères :
- '*' : Remplace un nombre indéfini de caractères (même aucun).
- '?' : Remplace un, et un seul, caractère.
Pour illustrer leur usage, considérons ces six fichiers :
- ex1.txt
- ex12.txt
- ex15.txt
- ex17.img
- doc.img
- docr.img
Et ces cinq expressions :
- "ex*" : Correspond à "ex1.txt ex12.txt ex15.txt ex17.img"
- "*.txt" : Correspond à "ex1.txt ex12.txt ex15.txt"
- "ex1?.txt" : Correspond à "ex12.txt ex15.txt"
- "doc*.img" : Correspond à "doc.img docr.img"
- "doc?.img" : Correspond à "docr.img"
De plus, le caractère '.', lorsque placé en début de nom de fichier ou dossier, indique que l'élément est caché par défaut. Il demeure toujours accessible, mais ne sera pas affiché par 'ls' à moins d'ajouter l'option "-a" (pour "all") en argument.
Q1.a) Faites afficher le contenu complet du dossier "td2". Quelle commande utilisez-vous?
Réponse : ls -a
Q1.b) Indiquez quels fichiers sont cachés :
Réponse : Fichiers .hidden_1 à .hidden_5
Q2.a) Créez un sous-dossier "hidden".
Réponse : mkdir hidden
Q2.b) En une seule commande, copiez-y tous les fichiers cachés, idéalement sans avertissement du terminal.
Réponse : cp .hidden* hidden/ Note : "cp .* hidden/" obtient le même résultat, mais produit un avertissement en lien avec les dossiers "." et "..".
Q3. Maintenant, répétez l'exercice en déplaçant tous les fichiers ayant pour extension ".txt" dans un sous-dossier "texte"
Réponse : mkdir texte mv *.txt texte/
Q4. Dans ce sous-dossier, supprimez en une seule commande tous les fichiers commençant par "vide" et qui se terminent par un suffixe de 10 et plus.
Réponse : rm vide_1?.txt ou, si vous êtes toujours dans le dossier "td2" : rm texte/vide_1?.txt
Partie 2 - Concaténation, redirection et tuyau
Nous allons maintenant mettre en application deux nouveaux concepts : la concaténation et la redirection de la sortie d'une commande.
On vous rappelle d'abord que chaque commande a ce qu'on nomme la sortie standard. Celle-ci est généralement attachée à l'affichage du terminal. En effet, la commande "ls" émet la liste des fichiers d'un dossier vers la sortie standard qui est, sans redirection, l'affichage du terminal. Voici les trois nouvelles commandes que nous allons utiliser pour exploiter la sortie standard :
- cat (concatenate) Lit le contenu de chacun des fichiers en argument vers la sortie standard.
- echo Répète tous les arguments (mais pas leur contenu!) vers la sortie standard.
- wc (word count) Affiche des statistiques (nombre de lignes, mots et caractères) sur le contenu en entrée standard.
Notez que les méta-caractères "*" et "?" sont toujours applicables. Essayez par exemple la commande "echo *.txt" dans le sous-dossier "texte" de la question 3. Pratique pour tester une commande avant de l'appliquer!
Maintenant, à quoi servent réellement ces deux commandes ? Si "cat" avec un seul nom de fichier permet d'en afficher le contenu rapidement, le fait d'en afficher plusieurs de suite peut sembler moins pratique. C'est avec la redirection que ces commandes prennent tout leur sens. Avec le caractère ">" en fin de commande, on peut rediriger la sortie standard vers un fichier. Ainsi, la commande "ls > liste" n'affichera pas la liste des fichiers d'un dossier, mais l'écrira dans un fichier nommé "liste", et "echo hello > test" permet de créer automatiquement un fichier nommé "test" et qui contient le mot "hello".
Tentons maintenant de mettre ces concepts en application !
Si vous avez bien répondu à la question Q3, le sous-dossier "texte" contient au moins deux fichiers : "a_m.txt" et "n_z.txt". Sinon, ils devraient toujours être dans le dossier "td2", mais tentez d'abord de répondre à Q3 !
Q5.a) Affichez à l'écran le contenu de ces deux fichiers séparément (en deux commandes).
Réponse : cat a_m.txt cat n_z.txt
Q5.b) À partir de ces deux fichiers, créez-en un troisième, a_z.txt, qui contiendra tout l'alphabet.
Réponse : cat a_m.txt m_z.txt > a_z.txt
Q5.c) Finalement, affichez le contenu du nouveau fichier à l'écran pour confirmer le résultat. Qu'est-ce que vous remarquez ?
Réponse : Il n'y a pas de saut de ligne entre le "m" et le "n". Commande : cat a_z.txt
Exercice supplémentaire : Tentez de recréer le contenu du fichier a_m.txt avec la commande echo, et répétez la création du fichier a_z.txt. Remarquez-vous une différence ? Il y aura normalement un saut de ligne entre le "m" et le "n". Pour éviter ce saut, la solution se trouve dans le manuel de la commande "echo" (commande "man"). Tentez de trouver l'option nécessaire !
Réponse : L'option "-n", qui laisse tomber le saut de ligne à la fin de la sortie de "echo".
Voyons maintenant un concept similaire à la redirection : le tuyau. Si toutes les commandes ont une sortie standard, elles ont également une entrée. Le tuyau, représenté par le caractère "|", permet de rediriger la sortie d'une commande vers l'entrée d'une autre. Par exemple, la commande "cat", lorsqu'on l'appelle sans arguments, lit les informations de l'entrée standard.
Pour vous en convaincre, lancez la commande "cat", tapez ce que vous voulez suivi de la touche Entrée quelques fois, et terminez avec la combinaison de touches Ctrl-C.
Qu'arrive-t-il ?
Si la sortie standard est automatiquement branchée à l'écran, l'entrée quant à elle est branchée à votre clavier. Ainsi, la commande "cat" ne fait que répéter ce qu'elle a reçu du clavier.
Il est à noter que la raison pour laquelle la répétition ne s'effectue qu'après la touche Entrée va au-delà du sujet de ce cours.
Q6. Avec les commandes "ls" et "wc", trouvez le nombre de fichiers se trouvant dans votre dossier en cours (indice : ls, lorsque sa sortie est redirigée vers un fichier ou un tuyau, affiche un nom de fichier par ligne).
Réponse : ls | wc Vous obtiendrez normalement le nombre de ligne de texte, soit le nombre de fichiers, avec la première valeur. Il n'y a pas de réponse exacte, étant donné que cela peut varier selon l'utilisateur et le dossier en cours.
Partie 3 - Lecture à la loupe
Les exercices précédents ont utilisé des fichiers de très petite taille. Or, il existe des outils bien pratique pour afficher le contenu de fichiers volumineux. En voici quelques-uns :
- less : Affiche le contenu d'un fichier, mais arrête le défilement écran par écran. Le contenu peut ensuite être parcouru avec les flèches de votre clavier.
- tail : N'affiche que les dernières lignes d'un fichier. Par défaut, il s'agit des 10 dernières lignes, mais Vous pouvez spécifier le nombre à l'aide d'une option (utilisez la commande "man" pour la trouver).
- od -cb (octal dump) : Affiche le contenu d'un fichier sous forme octale (base 8, chiffres de 0 à 7). La combinaison d'options "-cb" permet d'afficher à la fois les caractères reconnaissables ASCII et la valeur en base 8.
Pour mettre en application ces commandes, tentez premièrement d'exécuter la commande "od -cb chanson.mp3" à partir du dossier "td2".
Vous allez probablement voir défiler une quantité importante de texte. Vous pouvez utiliser Ctrl-C pour interrompre le défilement, mais comme le souligne la liste de commande, il y a un outil plus pratique...
Q7.a) Sauvegardez la sortie de la commande "od -cb chanson.mp3" dans un fichier "chanson.od".
Réponse : od -cb chanson.mp3 > chanson.od
Q7.b) Affichez le contenu de "chanson.od", mais écran par écran.
Réponse : less chanson.od
Q7.c) Répétez les exercices a) et b), mais sans fichier intermédiaire et en une seule commande.
Pour sauver du temps d'écriture, vous pouvez utiliser la flèche "Haut" de votre clavier à la ligne de commande pour parcourir les dernières commandes entrées et les modifier.
Réponse : od -cb chanson.mp3 | less
Partie 4 - Recherche rapide dans des fichiers texte
Nous avons commencé à manipuler de plus grands fichiers, mais à part les faire défiler écran par écran, nous n'avons pas fait grand chose d'utile. Par exemple, comment peut-on effectuer une recherche du même type que Ctrl-F dans GEdit ?
Pour cela, il existe la commande grep. Elle présente une multitude d'options, mais pour le moment nous allons nous limiter à sa forme la plus simple :
grep "expression" fichiers
L'expression est la séquence de caractères que vous souhaitez rechercher. Vous pouvez même omettre les guillemets s'il s'agit d'un seul mot. Le ou les arguments fichiers est simplement la liste des noms de fichiers dans lequel vous voulez effectuer votre recherche. Vous pouvez ne mettre qu'un seul nom et, comme "cat", "grep" va lire son entrée standard si vous laissez tomber le nom de fichier. Elle peut donc être utilisée avec le tuyau.
Note supplémentaire : "grep" supporte aussi ce qu'on appelle des expressions régulières incluant les meta-caractères "*" et "?". Ces expressions ont une syntaxe différente de celle utilisée pour sélectionner plusieurs fichiers, et elles ne sont pas à l'étude pour ce cours. Par contre, on vous suggère de vous en informer avec "man grep".
Nous allons maintenant travaillé avec un fichier "csv" (pour "comma-separated values"), un type de fichier texte populaire qui organise des données en tableaux où les colonnes sont séparées par des virgules. Généralement, la ligne précédent les données est l'en-tête décrivant le contenu de chaque colonne.
Un tel fichier se trouve dans le dossier TD2 : "mtl-hourly-01012015-01312015.csv".
Q8.a) À l'aide de "less", parcourez le début du fichier et trouvez à quelle colonne se trouve la température ("Temp (oC)").
Réponse : La septième colonne.
Q8.b) À l'aide de "grep", affichez toutes les mesures du 7 janvier 2015. Quelle température faisait-il à cet aéroport à 21 :00 ?
Réponse : La température à 21:00 était -24.3 C. grep "2015-01-07" mtl-hourly-01012015-01312015.csv
Il y a un deuxième fichier "csv" dans le dossier "td2" qui présente les mêmes données pour un autre aéroport.
Q9.a) En une seule commande "grep", affichez les données du 10 janvier à 12:00 pour les deux aéroports.
Réponse : grep "2015-01-10 12:00" *.csv
Q9.b) Répétez l'exercice précédent, mais cette fois-ci en vous servant du tuyau.
Réponse : cat *.csv | grep "2015-01-10 12:00"
Partie 5 : Traitements et manipulation des fichiers et des données
Pour cette partie vous aurez besoin des commandes suivantes :
- sort : permet de trier les lignes d'un fichier suivant l'odre lexicographique par défaut.
- cut : permet de supprimer une partie de chaque ligne d'un fichier
- uniq : permet d'éliminer les lignes dupliquées dans un fichier trié
- paste : permet de regrouper les lignes de différents fichiers
- tr : permet de transposer ou éliminer des caractères
Nous allons considérer un petit annuaire téléphonique qui est enregistré dans le fichier "annuaire.txt". Chaque ligne de cet annuaire est représentée par trois (3) colonnes séparées par un espace et représentent dans l'ordre le nom de famille, le prénom et le numéro de téléphone.
Q10.a) A l'aide de la commande "sort", triez dans l'ordre alphabétique l'annuaire et rangez le résultat dans un fichier nommé "annuaire-trie.txt"
Réponse : sort annuaire.txt > annuaire-trie.txt
Q10.b) A l'aide de la commande "cut" et à partir du fichier "annuaire-trie.txt", extrayez la liste des noms de famille dans un fichier nommé "noms-tries.txt". Il faut penser à utiliser les options (utiliser la commande "man cut") pour définir le séparateur de colonnes et pour choisir la colonne (aussi appelée champs ou field) appropriée.
Réponse : cut -d " " -f 1 annuaire-trie.txt > noms-tries.txt ou cat annuaire-trie.txt | cut -d " " -f 1 > noms-tries.txt
Q10.c) A partir du fichier "noms-tries.txt" et en utilisant la commande "uniq", suprimmez les répétitions dans la liste des noms de famille et rangez le résultat dans un fichier nommé "noms-tries-uniques.txt"
Réponse : uniq noms-tries.txt > noms-tries-uniques.txt
Q10.d) A l'aide de la commande "wc", comptez le nombre de lignes (donc le nombre de noms de famille différents) du fichier "noms-tries-uniques.txt"
Réponse : wc -l noms-tries-uniques.txt
Q10.e) En une seule commande et sans utiliser de fichiers intermédiaires, comptez le nombre de noms de famille différents dans l'annuaire.
Réponse : sort annuaire.txt | cut -d" " -f 1 | uniq | wc -l ou aussi cat annuaire.txt | cut -d" " -f 1 | sort | uniq | wc -l
Q11.a) On souhaite mettre les noms de famille de l'annuaire en lettres majuscules, pour cela nous allons extraire les informations de l'annuaire trié "annuaire-trie.txt" et les ranger dans trois fichiers correspondant à chaque colonne de l'annuaire. On souhaite donc avoir un fichier "noms.txt", "prenoms.txt", "telephones.txt" à partir du fichiers "annuaire.txt". A l'aide de la commande "cut" réalisez cette opération.
Réponse : cut -d " " -f 1 annuaire-trie.txt > noms.txt cut -d " " -f 2 annuaire-trie.txt > prenoms.txt cut -d " " -f 3 annuaire-trie.txt > telephones.txt
A noter que nous aurions pu aussi créer un seul fichier pour les prénoms et les numéros de téléphones. La commande "cut" permet simplement de faire cela. Pour vous aider regarder la page "man" de la commande "cut".
Réponse : cut -d " " -f 1 annuaire.txt > noms.txt cut -d " " -f 2,3 annuaire.txt > prenoms-telephones.txt
Q11.b) A l'aide de la commande "tr", mettez en lettres majuscules toutes les lignes du fichier "noms.txt" et sauvez le résultat dans le fichier "noms-majuscules.txt"
Réponse : cat noms.txt | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ > noms-majuscules.txt ou cat noms.txt | tr a-z A-Z > noms-majuscules.txt
Q11.c) A l'aide de la commande "paste", recomposez un annuaire à l'aide des fichiers "noms-majuscules.txt", "prenoms.txt" et "telephones.txt" et sauvegardez le résultat dans le fichier "annuaire-majuscule.txt"
Réponse : paste noms-majuscules.txt prenoms.txt telephones.txt > annuaire-majuscule.txt ou si un seul fichier pour les prénoms et numéros de téléphone a été utilisé paste -d" " noms-majuscules.txt prenoms-telephones.txt > annuaire-majuscule.txt Note : dans la seconde solution on ajoute le déliminiteur espace " " à l'aide de l'option "-d" de la commande "paste" pour garder l'homogéniété des séparateurs de champs.
Q12) En combinant les commandes "head" et "tail" (avec les options appropriées, cf les pages man), affichez les lignes 8 à 12 du fichier "annuaire-majuscule.txt"
Réponse : cat annuaire-majuscule.txt | head -12 | tail -5
Q13) A l'aide de la commande "grep", trouvez toutes les personnes qui ont un numéro de téléphone qui commence par "02"
Réponse : cat annuaire-majuscule.txt | grep " 02" Note: Attention au caractère espace avant le nombre "02".
Partie 6 : commande "find"
La commande "find" permet de trouver des fichiers suivant certains critières dans une hiérarchie de répertoires.
La forme standard d'appel à la commande "find" est
find chemin [options]
"chemin" représente l'adresse de l'aborescence que l'on veut exporer. Les options importantes de cette commande sont :
- -empty : trouve les fichiers ou répertoires vides
- -name motif : trouver les fichiers dont le nom de base (sans les répertoires du chemin d'accès), correspond au motif du shell.
- -iname motif : identique à l'option "-name" mais ne faisant pas la différence entre majusucules et minuscules (insensilbe à la casse)
- -type t : trouve les fichiers de type "t" où "t" peut être "d" pour dossier, "f" pour un fichier
- -exec commande ; : Exécute la commande sur chaque élément trouvé par "find". Tous les arguments suivants de "find" sont considérés comme des arguments pour la ligne de commande, jusqu'à ce qu'on rencontre un
;'. La chaîne '{}' est remplacée par le nom du fichier en cours de traitement. Ces deux chaînes peuvent avoir besoin d'être protégées du développement de la ligne de commande par le shell, en utilisant le caractère d'échappement (
') ou une protection par des apostrophes. La commande est exécutée depuis le répertoire de départ.
Q14) A l'aide de la commande "find", affichez tous les fichiers vides qui sont présents dans l'aborescence commençant à partir du dossier "td2"
Réponse : find td2 -empty -type f
Q15) A l'aide de la commande "find", affichez tous les dossiers contenus dans le répertoire mo101
Réponse : find mo101 -type d
Q16) A l'aide des commandes "find", trouvez tous les fichiers dont le nom contient la chaîne de caractères "nonstiff-a" et qui sont présents dans l'aborescence débutant avec le répertoire "simulation"
Réponse : find simulation -name "*nonstiff-a*"
Q17) A l'aide des commandes "find" et "cat", affichez le contenu de tous les fichiers dont le nom contient exactement la chaîne de caractères "stiff" et qui sont présents dans l'aborescence débutant avec le répertoire "simulation"
Réponse : find simulation -name "*_stiff*" -exec cat {} \; Note: il est important ici d'ajouter le caractère d'échappement '\' au caractère ";" car celui-ci à une signification particulière en Bash. Il permet de mettre en séquence deux commandes, par exemple, "cd ~; ls" aura pour effet de réaliser la commande "cd ~" puis quand celle-ci a terminé la commande "ls" est exécutée.
Q18) A l'aide des commandes "find" et "grep", affichez toutes les lignes qui contiennent le mot "ode45" dans les fichiers dont le nom contient la chaîne de caractères "nonstiff-d" et qui sont présents dans l'aborescence débutant avec le répertoire "simulation"
Réponse : find simulation -name "*nonstiff-d*" -exec grep "ode45" {} \;
Partie 7 - commande sed
La commande sed (pour stream editor) permet de manipuler facilement du texte pour en extraire de l'information ou faire des modifications en masse. En particulier cette commande permet de subsituer un texte par un autre dans un fichier. La syntaxe de cette opération est la suivante : sed -e 's/texte_a_trouver_et_a_remplacer/texte_de_remplacement/' fichier
- sed est le nom de la commande
- -e est l'option qui permet de définir le traitement à effectuer
- s/texte_a_trouver_et_a_remplacer/texte_de_remplacement/ définit un traitement de substitution d'un texte par une autre
- fichier est le nom du fichier qu'il faut traiter
Q1. Utilisez cette commande pour subsituer tous les prénoms "Gabriel" par "Gab" dans le fichier annuaire.txt
Réponse : sed -e 's/Gabriel/GAB/' annuaire.txt 2 substitutions doivent avoir lieu.