Sites


Introduction à la ligne de commande

CommandLineIntro: MultipleFiles

Moins cher en quantité

Dès que vous vous habituerez à la ligne de commande, vous allez chercher de nouvelles façons de faire plus en moins de temps.  Une des manières les plus faciles pour y arriver est de travailler en même temps sur plusieurs fichiers, ainsi au lieu de taper :

$ rm this
$ rm that
$ rm here
$ rm there

vous détruisez tous ces fichiers en une seule commande.  Beaucoup de commandes, dont rm, vous permettent simplement de spécifier en une fois comme arguments tous les fichiers que vous désirez effacer :

$ rm this that here there
    Il est encore possible de faire mieux !

    Les motifs (Globbing)

    Les motifs de nom de fichiers (File globbing) est la manière utilisée par le shell pour indiquer plusieurs fichiers en utilisant le nombre minimum de caractères. Le shell considère certain caractères comme des codes que vous pouvez utiliser pour spécifier des groupes d'objets que vous désirez manipuler avec les commandes. Ces caractères sont communément appelés "jokers" ("wildcards" en anglais) car, comme dans les jeux de cartes, ils peuvent représenter quoi que se soit.

    Le joker "*"

    Imaginons un répertoire contenant les fichiers :

    $ ls
    here  that  there  this
    

    que vous voulez effacer.  Le travail fastidieux de détruire les fichiers un par un peut devenir simple en utilisant *, le joker astérisque.

    $ rm *
    

    Lorsqu'elle est utilisée seule, l'astérisque fait référence à tous les éléments du répertoire exceptés ceux dont le nom commence par ".".  On dit que le shell développe le joker.  Connaissant le contenu du répertoire, le shell remplace l'astérisque par ces noms de fichier et exécute en fait la commande suivante :

    $ rm here that there this
    

    Il est possible également de combiner  * avec d'autres caractères pour la rendre sélective.

    $ rm t*
    $ ls
    here

    Que se passe-t-il ici ? Le shell considère d'abord le "t" et développe l'astérisque ensuite afin de sélectionner tous les fichiers dont le nom commence par un "t".  Si, par contre, vous aviez spécifié "h*", le shell aurait effacé tout fichier dont le nom commence par un "h". Revenons à notre répertoire original et effaçons les fichiers commençant par "h" :

    $ touch that there this
    $ rm h*
    $ ls
    that  there  this
    

    Le joker astérisque peut être placé n'importe où dans un mot. Utilisons plutôt la commande ls car il est plus facile avec elle de voir ce qui se passe avec les jokers :

    $ ls th*re
    there
    

    En passant de rm à ls, nous voyons un aspect important des jokers : ils ont utilisables avec n'importe quelle commande, car le shell les interprète avant de lancer la commande.  Il est en fait impossible de lancer un commande sans tenir compte des jokers, car c'est une caractéristique même du shell.  (Il y a heureusement peu de chance que vous ayez à manipuler un nom de fichier contenant réellement une astérisque.)

    Plusieurs astérisques peuvent aussi être utilisées ensembles.  Vous pouvez, par exemple, trouver de cette manière les noms de fichiers contenant une série de caractères, mais dont le début et la fin diffèrent.  Essayons sur nos quatre fichiers :

    $ ls *i*
    this

    L'astérisque est souvent utilisée pour effacer tous les fichiers d'un type donné. Si, pas exemple, vous avez travaillé sur un grand nombre de photographies et que, lorsque vous avez terminé, vous voulez nettoyer les fichiers qui se terminent en .jpg, vous pouvez effacer l'ensemble de ses fichiers dans le répertoire courant de la manière suivante :

    $ rm *.jpg

    Si certains fichiers se terminent en .jpg et d'autres en .jpeg. L'astérisque peut toujours rendre le nettoyage aisé :

    $ ls *.jp*g

    Supposons, maintenant, que les fichiers JPEG sont éparpillés dans plusieurs sous-répertoires. Vous avez les répertoires nommés photos1, photos2, photos3, et ainsi de suite, chacun contenant des fichiers JPEG que vous voulez supprimer.  Un premier joker peut vous aider à lister le contenu des ces sous-répertoires : 

    $ ls photos*
    photos1:
    centraal_station.jpg    nieuwe_kerk.jpg
    
    photos2:
    ica.jpeg                sanders_theater.jpeg
    
    photos3:
    bayeux_cathedral.jpeg   rouen_cathedral.jpeg    travel.odt
    

    Et vous pouvez indiquer un répertoire en plus du noms des fichiers que vous supprimez :

    $ rm photos*/*.jp*g
    $ ls photos*
    photos1:
    
    photos2:
    
    photos3:
    travel.odt

    Seul le fichier travel.odt reste (car il ne correspond pas à "*.jp*g") comme trace de tous les voyages que vous avez faits.

    Il existe, cependant, une limite au joker astérisque.  Par défaut, il ne sélectionnera pas les fichiers cachés (ceux dont le nom commence par un point,  la commande ls -a vous permettra de lest voir).

    $ ls -a
    .
    ..
    .hidden
    this
    that
    here
    there
    $ rm *
    $ ls -a 
    .
    ..
    .hidden

    Si vous désirez effacer ces fichiers cachés en utilisant un joker, il est nécessaire d'ajouter un point devant le joker. Notez que dans ce cas les fichiers normaux (ceux qui ne sont pas cachés/dont le nom ne débute pas par un point) ne seront pas effacés :

    $ ls -a
    .
    ..
    .hidden
    here
    $ rm .*
    $ ls -a 
    .
    ..
    here
    

    Enfin, il est important de noter que l'astérisque peut au besoin correspondre à une chaîne vide, comme le montre l'exemple suivant :

    $ ls task*
    task  taskA  taskB  taskXY

    Il en est ainsi parce que l'astérisque correspond à zéro ou plusieurs apparitions.  Ainsi, comme dans l'exemple précédant,  "task*" correspond à tout nom de fichier qui commence par "task" même si ce nom est simplement "task".

    ATTENTION: Lorsque vous utilisez uniquement une astérisque ("*") avec rm, et fondamentalement tout autre commande, c'est toujours une bonne idée d'ajouter un marqueur de fin d'option  ("--") devant le joker, de la manière suivante :

    $ rm -- *

    Par exemple dans le cas suivant :

    $ ls
    

    -r directory1 directory2 file1.txt

    $ rm *

    Normalement, rm ne supprimera pas les sous-répertoires ni leur contenu, cependant, ici, tout le contenu du répertoire en ce compris les sous-répertoires seront effacés.  Il en est ainsi parce que l'astérisque ("*") est étendue en "-r directory1 directory2 file1.txt". Et quoique "-r" soit un nom de fichier, rm le traitera comme une option et pensera qu'il lui est demandé d'effacer également les sous-répertoires et leur contenu. Utiliser le marqueur de fin d'options ("--") empêchera rm de considérer quoi qui suive le marqueur comme une option.  Pour cette raison, c'est généralement une bonne idée de toujours utiliser un marqueur de fin d'options après avoir introduit une commande et ses options, s'il y en a, afin d'éviter que la commande traite un nom de fichier comme une option.

    Le joker "?"

    Le "?" ou le joker point d'interrogation est très proche du joker astérisque.  Leur différence fondamentale est que le point d'interrogation ne prend la place que d'un seul caractère.

    $ ls task*
    task  taskA  taskB  taskXY
    $ ls task?
    taskA  taskB
    $ ls task??
    taskXY

    Comme nous l'avons vu plus haut, l'astérisque couvre tous les fichiers qui commence par "task". Un seul point d'interrogation ne sélectionne que les fichiers qui ont un seul caractère après "task".  L'usage de deux points d'interrogation requerra la présence d'exactement deux caractères à cette position.

    Les jokers "[ ]"

    Les jokers "crochets" sont encore plus spécifiques, en dénotant un ensemble donné de caractères. La commande ls suivante utilise l'option -1 (le chiffre "un"), qui signifie "liste une entrée du répertoire par ligne". Cette option nous permettra de faire plus aisément la différence entre les fichiers de cet exemple.

    $ ls -1
    file_1
    file_2
    file_3
    file_a
    file_b
    file_c 
    

    En utilisant les crochets, certains fichiers peuvent être effacé sans devoir spécifier le nom en entier. 

    $ rm file_[13ac]
    $ ls -1
    file_2
    file_b
    

    L'ordre des caractères inclus entre les crochets n'importe pas.

    En utilisant le trait d'union avec les crochets, il est possible de sélectionner un intervalle de fichiers. Partons d'un répertoire contenant beaucoup de fichiers dont le nom termine par des chiffres :

    $ ls
    file_1
    file_2
    file_3
    ...
    file_9
    

    De prime abord, on pourrait être tenté d'utiliser le joker astérisque.  Quid, cependant, si les seuls fichiers à effacer sont ceux terminant par 2-6? Il est possible de lister chacun des chiffres entre crochets, mais cela veut dire introduire les cinq chiffres.  Heureusement, il y a une façon de faire bien plus facile.

    $ rm file_[2-6]

    Les seuls fichiers restant sont 1 et 7-9.  En utilisant dans les crochets, le trait d'union entre deux chiffres, le shell développera le motif en créant un nom pour chaque chiffre entre les valeurs à gauche et à droite du trait.

    Les intervalles ne fonctionnent pas qu'avec les chiffres. Ils acceptent également les lettres.

    $ ls -1
    file_a
    file_b
    file_c
    file_d
    $ rm file_[a-c]
    $ ls -1
    file_d
    

    Les intervalles et les caractères peuvent être combinés dans un seul motif utilisant les crochets.

    $ ls -1
    file_a
    file_b
    file_c
    file_1
    file_2
    $ rm file_[a-c12]
    $ ls
    

    Les groupes de caractères peuvent être "inverser" en les préfixant d'un caractère ^ (accent circonflexe) :

    $ ls -1
    file_a
    file_b
    file_c
    file_d
    file_1
    file_2
    $ ls -1 file_[^c-z2-9]
    file_a
    file_b
    file_1
    

    ATTENTION: L'usage des intervalles entre crochets peuvent parfois devenir délicat.  La manière l'intervalle est développé peut dépendre des paramètres régionaux (locale)  (dans certains cas [A-C] pourrait signifier [ABCabc], tandis que dans d'autres il sera équivalent à [ABC]). Une règle de base est toujours connaître les fichiers sur lesquels vous travaillez.  Pour ce faire, vous pouvez simplement substituer echo ou ls à la commande que vous avez l'intention d'exécuter :

    $ ls -1 file[A-b]
    fileA
    fileB
    filea
    fileb

    Cela permet de s'assurer que le motif sélectionne les fichiers que vous voulez traiter.

    L'expansion des accolades

    Nous avons vu qu'il est possible d'obtenir un intervalle de caractères qui couvre un chiffre (0-9 dans nos exemples) mais que faire si nous devons sélectionner des fichiers qui utilisent des nombres à deux ou trois chiffres ?

    $ ls -1
    file_1
    file_2
    file_3
    ...
    file_78
    $ rm file_[1-20]
    $ ls -1
    file_3
    ...
    file_78

    Les motifs à base de crochets n'interprète qu'un seul caractère à la fois y compris dans les intervalles, "1-20" n'est pas interprété comme un intervalle numérique mais comme les caractères  : "1", "-", "2", et "0".   Seuls "file_1" et "file_2" sont dès lors effacer car ce sont les seuls qui correspondent.  Si vous désirez utiliser des intervalles plus large que  0-9, vous devez recourir à l'expansion des accolades qu'offre Bash, "{début..fin}".

    $ rm file_{1..20}

    Dans un intervalle entre accolades,  la succession de deux points est utilisée comme séparateur à la place du trait d'union.

    Les accolades peuvent également être utilisées pour traiter des séries de fichiers présentant un motif commun mais avec des différences subtiles.  Par exemple :

    $ ls
    file.txt
    file.pdf
    file.pl
    file.odf

    Si vous désirez seulement effacer les fichiers pdf, odf, et txt vous pouvez spécifier entre accolades la liste des chaînes de caractères séparées par des virgules :

    $ rm file.{txt,pdf,odf}
    $ ls
    file.pl

    Et si rien ne correspond

    Supposons que vous spécifiiez un joker ou un motif et que le shell ne trouve aucun fichier qui lui corresponde :

    $ ls -1
    file_a
    file_b
    file_c
    file_d
    $ rm file?
    rm: cannot remove `file?': No such file or directory
    

    Lorsqu'aucun fichier ne correspond à un motif, le shell le passe tel quel au programme.  C'est pourquoi le message d'erreur provient du programme rm, et non du shell.

    Désactiver un joker

    Bien, nous savons maintenant que le shell passera les jokers (ou motifs) comme paramètres au programme lorsqu'il ne trouve aucun fichier correspondant, mais que faire lorsque nous devons utiliser dans un paramètre du programme que nous voulons exécuter un caractère qui est aussi un joker?  Voici un exemple courant : nous désirons lister tous les fichiers dont le nom contient une astérisque devant 'file'.

    $ ls 
    2file
    *file
    *?****[a-b]
    

    Nous voulons obtenir *file, mais le résultat est :

    *file   2file                                                                   

    Pourquoi? Parce que l'astérisque est un joker et le shell la développe avant d'exécuter ls.  Ainsi après l'expansion, la ligne de commande deviendra :

    $ ls *file 2file

    Si nous désirons que ls trouve une asterisque, il faut utiliser un autre moyen.

    La barre oblique inverse,  "\",  (backslash en anglais), demande au shell de traiter le caractère suivant comme un caractère normal et de n'effectuer aucune expansion.

    $ ls \*file
    *file
    

    Comme l'astérisque est le caractère juste après la barre oblique inverse, le shell la communique non modifiée à  ls.  En d'autres mots, la barre oblique inverse annule ou inactive l'astérisque.

    La barre oblique inverse marche bien tant qu'il n'y a que peu de caractères jokers à passer à un programme, que faire, par contre, si nous devons passer une chaîne de caractère comme  *?****[a-b] qui contient beaucoup de caractères normalement interprétés comme des jokers ? L'usage de la barre oblique inverse pour les inactiver conduirait à marquer chaque caractère de la chaîne.  La courte chaîne terminerait en : \*\?\*\*\*\*\[a-b\].  Au lieu de doubler le nombre de caractères tapés, nous pouvons utiliser une paire d'apostrophes.

    $ ls '*?****[a-b]'
    *?****[a-b]
    

    Toute chaîne placée entre apostrophes ne sera pas modifiée par le shell même si elle est remplie de jokers.  Vous ne pouvez, cependant, pas utiliser d'apostrophe dans une chaîne placée entre apostrophes comme :

    $ ls '*?***'*[a-b]'
    

    Donc, si il vous arrive un jour d'avoir un fichier dont le nom contient des apostrophes et ressemble à quelque chose comme :

    *?*'**'*[a-b]
    

    Il n'y a pas d'autre solution que d'inactiver séparément chaque apostrophe de la manière suivante :

    $ ls '*?*'\''**'\''*[a-b]' 

    Il suffit simplement de remplacer chaque apparition dans le nom de fichier d'une apostrophe par '\''.


    Il y a une erreur de communication avec le serveur Booktype. Nous ne savons pas actuellement où est le problème.

    Vous devriez rafraîchir la page.