Le dot m’habite

Il est des fois où on erre parmi les répertoires depuis son terminal : cd par-ci, cd par-là… Avancer dans 3 sous-dossiers, remonter de 7… Parfois on ne sait plus combien de « .. » il va falloir enchaîner… Pourtant, le nom du dossier (lointain parent), lui, il est juste là, et ce fichu principe de remonter les niveaux un à un… En plus avec la quasi assurance de devoir saisir, dans une seconde commande, un ultime « cd .. » … Bref, des fois, c’est quand-même chiant ! Une petite fonction en Bash, et les « cd ../../.. […] /../../.. » vont vite décéder.

Dans la fonction ci-dessous, les commandes classiques que sont test, pwd et sed, vont nous permettre de remonter au répertoire qui aura été saisi en argument (pourvu que celui-ci existe).

function dcd ()
{
    if test `pwd | sed -e "s/\(.*\<${1}\>.*\)/\!/g"` = '!'
    then
        niveaux=`pwd | sed -e "s;.*\<${1}\>/*\(.*\);\1;" -e "s/\<[^/]*\>/../g"`

        test ${#niveaux} -gt 1 && cd $niveaux
    fi
}

Avant que vous ne soyez pris(e) de panique au vu de ce bout de code (les expressions régulières ont parfois un côté obscur), quelques explications s’imposent peut-être…

Le test qui conditionne le if, permet de vérifier que le paramètre $1 constitue bien le nom d’un des répertoires supérieurs :

  1. on exécute d’abord pwd pour connaître le chemin complet
  2. sed permet ensuite de transformer tout ce chemin en un seul caractère « ! », à l’unique condition que le paramètre $1 soit bien trouvé (en tant que mot au sens des expressions régulières)
  3. si la commande retourne « ! », alors le contenu du if est exécuté

Une fois dans le if, avec l’assurance que le répertoire cible existe, le nombre de répertoires à remonter va être stocké dans une variable « niveaux ». En voici le principe :

  1. on exécute encore une fois pwd, toujours pour connaître le chemin complet
  2. une première expression est soumise à la commande sed (premier « -e » ), afin de retirer de la chaîne tous les caractères devant le répertoire cible (donc en amont), et le répertoire cible avec
  3. une seconde expression est ensuite soumise à sed (deuxième « -e » ), pour remplacer chacun des répertoires encore présents par les fameux deux points « .. »
  4. en testant la longueur de la chaîne de « ../../.. » produite, on s’assure enfin de devoir remonter un certain nombre de niveaux, et c’est à cette seule condition qu’est exécuté le cd $niveaux

Après enregistrement de ce script dans un fichier, et un petit « source … » sur ce même fichier, la commande dcd fraîchement créée peut enfin être testée dans le terminal.

# Là, ça marche :
mynameis@localhost:/etc/locale/fr/LC_MESSAGES$ dcd locale
mynameis@localhost:/etc/locale$
# Là, ça marche pas, et heureusement :
mynameis@localhost:/etc/locale/fr/LC_MESSAGES$ dcd et
mynameis@localhost:/etc/locale/fr/LC_MESSAGES$

Bon… Tout ça c’est bien, mais c’est un peu lourd-dingue alors qu’il n’y a pas de quoi casser trois pattes à un canard… Voici une deuxième solution qui a le mérite d’être plus robuste, tout en étant nettement plus lisible.

function dcd ()
{
    increment=0
 
    for directory in `pwd | sed -e "s/ /5PAC3/g" -e "s/\// /g"`
    do
        directory=`echo $directory | sed "s/5PAC3/ /g"`
        test "$increment" -eq 1 && cd ..
        test "$directory" = "$1" && increment=1
    done
}

Le principe de cette nouvelle version est très simple :

  1. à l’aide de pwd, on dresse la liste des dossiers en amont, que l’on sépare par des espaces avec sed
  2. la chaîne «5PAC3», comme pour un précédent article, nous permet de sauvegarder les éventuels espaces dans le nom des répertoires
  3. pour chaque répertoire listé, on exécute alors le contenu de la boucle for :
    • on recouvre d’abord les espaces précédemment convertis en chaîne «5PAC3»
    • dès que l’on arrive au dossier cible, on le signale en mettant à jour la variable $increment
    • si le dossier cible a été dépassé dans la liste, alors on sait qu’il faut remonter d’un niveau via un « cd .. » , à chaque nouveau passage

Les solutions ne manquent donc pas, et il y en a, à n’en pas douter, sûrement d’autres ; et même meilleures que ces deux-ci.

Creative Commons License
Publié sous licence Creative Commons.