3 - Chasse au trésor de Bilbon

Ceci est une suite d’exercices pour vous exercer en vue de l’examen d’environnement de travail qui pourra éventuellement avoir un format similaire. Il faut donc être prêt pour ne pas se faire piéger par le caractère linéaire de l’examen.

Aucunes solutions ne vous sera donnée. Mais vous avez un mois d’ici l’examen pour échanger entre vous sur la meilleure façon d’arriver au terme de cet exercice.

Merci aux collègues de Télécom SudParis qui ont mis en place cet exercice.

Voici l’ultime trace (un peu opaque) du trésor confié à Bilbon lors de l’un de ses longs voyages itinérant de la fin du XXè siècle.

« Face à la clé du trésor cachée dans les itinéraires signés de mes nombreux voyages à travers de vastes pays de la fin du siècle dernier, l’anagramme des premières lettres des trois premières lignes selon l’ordre alphabétique portant le mot “à” en garantira l’authenticité. La clé ainsi découverte, il vous faudra la réorganiser selon un ordre lexicographique de troisième champ afin d’en extraire les 3è mots des couples de lignes de tête et de queue de lignes, et ainsi découvrir le chemin jusqu’au trésor ! »

Mise en place de la chasse au trésor (∼5mn).

  1. Récupérez l’archive des carnets de voyage de Bilbon en utilisant la commande wget.
wget https://cours-mf.gitlabpages.inria.fr/if104/advanced/03_chasse/CarnetsDeVoyage.tar.gz
  1. Extrayez l’archive.

Identification du voyage (∼1h10)

Objectifs: Identifier le répertoire dans lequel se trouve la clé du trésor.

La clé du trésor est cachée au sein d’un des répertoires de l’archive extraite. Chacun des répertoires correspond à un voyage, dont chacun des noms a été construit sur le même modèle : <année>-<lieu>, associé aux date et destination du voyage entrepris. Le champ année est toujours constitué de quatre chiffres. Quant au champ lieu, il correspond soit à un pays, et dans ce cas il commence par une majuscule, soit à une ville et il commence par une minuscule. Les deux champs sont séparés soit par un tiret haut, soit par un tiret bas.

La clé du trésor ayant été cachée lors d’un voyage itinérant à la fin du siècle dernier, nous sommes à la recherche d’un répertoire dont la date de création est comprise entre 1970 et 1999, et dont le lieu référence un pays. Par exemple, 1986-Bolivie.

Afin de mener à bien la recherche de la clé du trésor, nous vous proposons de procéder de manière incrémentale. Pour cela, vous allez écrire un script nommé chasse.sh que vous modifierez à chaque étape.

À chaque étape, pensez à vérifier que votre script est correct en l’exécutant.

1. Le script pour faire la chasse

  1. Commencez par écrire le script nommé chasse.sh dans le répertoire courant (c.-à-d., le répertoire parent de CarnetsDeVoyage ) avec les bons droits et l’entête adéquate pour pouvoir l’exécuter.

  2. Ce script doit définir une variable nommée base, et lui affecter le chemin CarnetsDeVoyage.

    Lancez votre script et vérifiez que votre script est correct en affichant cette variable à l’aide d’un echo.

    Dans toute la suite de l’exercice, nous supposons que votre répertoire courant est le répertoire parent de CarnetsDeVoyage.

    L’exécution de votre script doit donner:

$ ./chasse.sh
CarnetsDeVoyage

2. Sélectionner les bons voyages

Votre script doit maintenant sélectionner tous les fichiers qui correspondent à des voyages. En procédant étape par étape et en utilisant des motifs de filtrage bash, on va créer une fonction qui permette de filtrer les répertoires intéressants. Pour cela, enlever le echo et ajouter en fin de script:

filtrage() {
}

filtrage

Modifiez la fonction filtrage étape par étape pour afficher:

  • tous les fichiers dont le nom commence par 19 se trouvant dans le répertoire $base,
  • tous les fichiers dont le nom commence par 19 et est suivi par un chiffre entre 7 et 9,
  • tous les fichiers dont le nom commence par 19, est suivi par un chiffre entre 7 et 9, et est suivi d’un chiffre quelconque,
  • tous les fichiers dont le nom commence par 19, est suivi par un chiffre entre 7 et 9, est suivi d’un chiffre quelconque, et est suivi soit par un tiret bas soit par un tiret haut.
  • tous les fichiers dont le nom commence par 19, est suivi par un chiffre entre 7 et 9, est suivi d’un chiffre quelconque, est suivi soit par un tiret bas soit par un tiret haut, et est suivi d’une chaîne de caractères quelconque dont la première lettre est une majuscule.

Pour vous aider, votre fonction devrait contenir une commande du type:

echo $base/[un-motif-ici]

Vérifiez manuellement que les entrées sélectionnées correspondent bien aux descriptions données. Vous devriez avoir quelque chose similaire à ce qui suit_

$ ./chasse.sh
1972-Italie
1985-Allemagne
1990_Perou
...

À ce stade, il doit vous rester 4 entrées candidates car il n’y a eu aucun filtre sur le type des entrées considérées.

3. Trouver le voyage le plus long

Nous sommes à la recherche d’un plan d’itinéraire. Nous pouvons donc raffiner notre quête en nous limitant aux répertoires dans lesquels le trésor aura possiblement été caché. Avant de vérifier si un fichier est un répertoire, votre script doit d’abord itérer sur les noms trouvés à la question précédente.

Au lieu d’afficher les noms trouvés comme précédemment, votre script doit donc itérer sur les noms trouvés avec la fonction précédente, et n’afficher que ceux qui sont des répertoires. Ajouter les lignes suivantes à la fin de votre script:

identify_rep() {
}

identify_rep $( filtrage )

Cette fonction prend en parametre une liste des noms trouvés précédemment et doit d’abord itérer sur les noms trouvés à la question précédente.

  • Commencez par essayer d’afficher uniquement les noms de répertoires avec echo dans une boucle.
  • Modifiez le corps de la boucle de façon à n’afficher que les répertoires.
  • Le voyage ayant été long, votre script doit sélectionner le répertoire le plus volumineux. Vous devez donc modifier votre boucle de façon à stocker, dans une nouvelle variable nommée rep, le répertoire le plus volumineux. Nous procédons en plusieurs étapes. Dans un premier temps, remplacez le echo de la première étape de façon à afficher la taille de chacun des répertoires (sans les sous-répertoires). (cf la commande du)
  • En utilisant un tube/pipe et par exemple la commande cut, n’afficher que la taille des répertoires (c.-à-d., sans leur nom)
  • Vous avez désormais toutes les informations nécessaires pour ne stocker que le répertoire le plus gros dans la variable rep
  • Affichez la valeur trouvée pour rep avec echo

Si vous obtenez:

$ ./chasse.sh
CarnetsDeVoyage/1978-Senegal

Bravo ! Vous avez découvert le voyage qui héberge la clé du trésor !

Identification de la clé du trésor (∼30mn)

Objectifs: Trouver le fichier qui sert de clé au trésor !

1. Trouver les itinéraires

Pour identifier le fichier qui sert de clé, nous procédons étape par étape. Commencez par étendre le script chasse.sh avec ces lignes:

find_itineraries() {
}

rep=$( identify_rep $( filtrage ) )
find_itineraries $rep

Faites en sorte que cette nouvelle fonction find_itineraries affiche tous les fichiers ordinaires se trouvant dans le répertoire passé en paramètre ou dans un de ses sous-répertoires, et dont le nom contient la chaîne "Itineraire"

À cette question, il ne faut pas utiliser de recherche par motif comme vous l’avez fait au début de l’exercice 2. En effet, une recherche par motif cherche des fichiers dans un répertoire mais pas dans les sous-répertoires. À cette question, il faut donc utiliser la commande find qui permet de chercher des fichiers dans un répertoire et dans ses sous-répertoires.

2. Trouver la signature de Bilbon

Parmi les fichiers filtrés précédemment par la fonction find_itineraries, nous souhaitons trouver celui qui contient la signature de Bilbon (Tout simplement celui qui contient la chaîne bilbon). La solution retenue sera implémentée dans une fonction find_signature qui prend en paramètre les fichiers filtrés précédemment.

Modifiez la fin de votre script pour avoir:

find_signature() {
}

rep=$( identify_rep $( filtrage ) )
find_signature $( find_itineraries $rep )

La fonction find_signature doit afficher le nom de l’itinéraire qui contient le motif Bilbon

Noter que:

  • la commande grep renvoie vrai si elle trouve une ligne qui correspond au motif, et faux sinon.
  • vous pouvez utiliser les redirections de flux vers /dev/null pour éliminer l’affichage de grep

3. Vérifier que le fichier trouvé est le bon

Le but de cette question est de résoudre une première partie de l'énigme : « l’anagramme des premières lettres des trois premières lignes selon l’ordre alphabétique portant le mot “à” en garantira l’authenticité ». Au lieu d’afficher le fichier trouvé comme à la question précédente, utilisez des tubes pour chaîner les commandes suivantes dans votre script.

  • affichez toutes les lignes contenant le caractère à dans le fichier retourner par la fonction find_signature
  • triez ces lignes en suivant l’ordre lexicographique,
  • ne gardez que les trois premières lignes du fichier
  • ne gardez que la première lettre de chaque ligne
  • supprimez les retours à la ligne \n

Nous vous conseillons vivement de procéder étape par étape.

Si Bilbon ne se moque pas de vous, vous devriez obtenir un anagramme du mot « CLE ». Remarquez que, comme vous avez trié les lignes en suivant l’ordre lexicographique, cet anagramme ne peut être que « CEL ». Lorsque vous trouvez le fichier contenant l’anagramme du mot « CLE », vous devez stocker le nom de ce fichier dans une variable nommée cle

Pour vous assurer que votre script est correct, affichez la valeur de cette variable à la fin du script. Si votre script est correct, il devrait vous afficher le fichier contenant l’anagramme du mot « CLE ».

Bravo ! Vous avez identifié le fichier contenant la clé !

Ultime étape : la découverte du trésor ! (∼45mn)

Maintenant que vous avez identifié le fichier contenant la clé du trésor, vous allez (enfin !) pouvoir trouver le trésor.

Nous vous rappelons que la fin de l'énigme est : « La clé ainsi découverte, il vous faudra la réorganiser selon un ordre lexicographique de troisième champ afin d’en extraire les 3è mots des couples de lignes de tête et de queue de lignes, et ainsi découvrir le chemin jusqu’au trésor ! »

  1. Nous commençons par trier le contenu du fichier trouvé précédemment selon un ordre lexicographique de troisième champ. Dans le script chasse.sh, faites en sorte de n’afficher que ce résultat.

    Note: Par défaut, la commande sort de Linux ignore la casse, mais ce n’est pas le cas sur un MacOS. Pour cette raison, les utilisateurs de MacOS doivent ignorer la casse en utilisant l’option -f

  2. « […] extraire les 3e mots des couples de lignes de tête et de queue de lignes […] ». Pour réussir à résoudre cette partie de l'énigme, nous vous proposons de:

  • éliminez les lignes vides,
  • Filtrez le résultat de la commande précédente de façon à ne conserver que les lignes qui contiennent du texte
  • Sauvegardez ce résultat dans un fichier nommé Itineraire_trie.txt
  • Isolez les deux premières lignes du fichier Itineraire_trie.txt et sauvegardez-les dans un fichier nommé Itineraire_trie_compact.txt
  • Isolez les deux dernières lignes du fichier Itineraire_trie.txt et ajoutez-les au fichier nommé Itineraire_trie_compact.txt
  • Stockez dans une variable nommée mots les troisièmes mots de chacune des lignes de Itineraire_trie_compact.txt
  • Supprimez les fichiers Itineraire_trie.txt et Itineraire_trie_compact.txt
  • Enfin, affichez le contenu de la variable mots
_Nous vous conseillons de procéder étape par étape et de vérifier, à chaque étape, que votre code fonctionne correctement._
  1. Afin d’afficher le trésor, il faut d’abord reconstituer le chemin vers le trésor dans une variable nommée tresor. Pour cela, il faut ajouter des / entre les différents mots de la variable mots,

  2. Afficher la variable tresor

  3. Ultime étape ! Au lieu d’afficher le chemin du trésor, affichez son contenu.

    Félicitations !!! Vous avez trouvé le trésor de Bilbon.