9. Chaînes de caractères

9.1. Protection de caractères

Le shell utilise différents caractères particuliers pour effectuer ses propres traitements ($ pour la substitution, > pour la redirection de la sortie standard, * comme caractère générique, etc.). Pour utiliser ces caractères particuliers comme de simples caractères, il est nécessaire de les protéger de l'interprétation du shell. Trois mécanismes sont utilisables :

  • Protection d'un caractère à l'aide du caractère \

    Ce caractère protège le caractère qui suit immédiatement le caractère \.

    $ echo \*     => le caractère * perd sa signification de caractère générique
    *
    $ echo *
    tata toto
    $
    $ echo \\     => le deuxième caractère \ perd sa signification de caractère de protection
    \
    $ echo N\'oublie pas !
    N'oublie pas !
    $

    Le caractère \ permet également d’ôter la signification de la touche Entrée. Cela a pour effet d’aller à la ligne sans qu’il y ait exécution de la commande. En effet, après saisie d’une commande, l’utilisateur demande au shell l’exécution de celle-ci en appuyant sur cette touche. Annuler l’interprétation de la touche Entrée autorise l’utilisateur à écrire une longue commande sur plusieurs lignes.

    Dans l’exemple ci-dessous, le shell détecte que la commande interne echo n’est pas terminée ; par conséquent, bash affiche une chaîne d’appel différente matérialisée par un caractère > suivi d’un caractère espace invitant l’utilisateur à continuer la saisie de sa commande.

    $ echo coucou \Entrée
    > salut Entrée   => terminaison de la commande : le shell l’exécute !
    coucou salut
    $

  • Protection de caractères à l'aide d'une paire de guillemets "chaîne"

    Tous les caractères de chaîne sauf $ \ ` " sont protégés de l'interprétation du shell. Cela signifie, par exemple, qu’à l’intérieur d’une paire de guillemets le caractère $ sera quand même interprété comme une substitution, etc.

    $ echo "< * $PWD * >"
    < * /home/sanchis * >
    $
    $ echo "< * \"$PWD\" * > "
    < * "/home/sanchis" * >
    $

  • Protection totale 'chaîne'

    Entre une paire d’apostrophes (′), aucun caractère de chaîne (sauf le caractère ') n'est interprété.

    $ echo '< * $PWD * >'
    < * $PWD * >
    $

9.2. Longueur d'une chaîne de caractères

Syntaxe : ${#paramètre}

Cette syntaxe est remplacée par la longueur de la chaîne de caractères contenue dans paramètre. Ce dernier peut être une variable, un paramètre spécial ou un paramètre de position.

$ echo $PWD
/home/sanchis
$ echo ${#PWD}
14   => longueur de la chaîne /home/sanchis
$
$ set "au revoir"
$ echo ${#1}
9   => la valeur de $1 étant au revoir, sa longueur est 9
$
$ ls >/dev/null
$
$ echo ${#?}
1   => contenue dans $?, la valeur du code de retour de ls
$   => est 0, par conséquent la longueur est 1

9.3. Modificateurs de chaînes

Les modificateurs de chaînes permettent la suppression d'une sous-chaîne de caractères correspondant à un modèle exprimé à l'aide de caractères ou d’expressions génériques.

  • Suppression de la plus courte sous-chaîne à gauche

    Syntaxe : ${paramètre#modèle}

    $ echo $PWD
    /home/sanchis
    $
    $ echo ${PWD#*/}
    home/sanchis      => le premier caractère / a été supprimé
    $
    $ set "12a34a"
    $
    $ echo ${1#*a}
    34a               => suppression de la sous-chaîne 12a
    $

  • Suppression de la plus longue sous-chaîne à gauche

    Syntaxe : ${paramètre##modèle}

    $ echo $PWD
    /home/sanchis
    $
    $ echo ${PWD##*/}
    sanchis   => suppression de la plus longue sous-chaîne à gauche se terminant par le caractère /
    $    
    $ set 12a34ab
    $
    $ echo ${1##*a}
    b
    $

  • Suppression de la plus courte sous-chaîne à droite

    Syntaxe : ${paramètre%modèle}

    $ echo $PWD
    /home/sanchis
    $ echo ${PWD%/*}
    /home
    $
  • Suppression de la plus longue sous-chaîne à droite

    Syntaxe : ${paramètre%%modèle}

    $ eleve="Pierre Dupont::12:10::15:9"
    $
    $ echo ${eleve%%:*}
    Pierre Dupont
    $

    La variable eleve contient les prénom, nom et diverses notes d'un élève. Les différents champs sont séparés par un caractère deux-points. Il peut manquer des notes à un élève (cela se caractérise par un champ vide).

9.4. Extraction de sous-chaînes

  • ${paramètre:ind} : extrait de la valeur de paramètre la sous-chaîne débutant à l'indice ind. La valeur de paramètre n’est pas modifiée.

    Attention : l'indice du premier caractère d'une chaîne est 0

    ch="abcdefghijk"
    	01234567..10
    	
    echo ${ch:3} affiche defghijk

  • ${paramètre:ind:nb} : extrait nb caractères à partir de l'indice ind.

    ch="abcdefghijk"
    	01234567..10					
    					
    $ echo ${ch:8:2}
    ij
    $ set ABCDEFGH
    $
    $ echo ${1:4:3}
    EFG
    $

9.5. Remplacement de sous-chaînes

  • ${paramètre/mod/ch} 

    Bash recherche dans la valeur de paramètre la plus longue sous-chaîne satisfaisant le modèle mod puis remplace cette sous-chaîne par la chaîne ch. Seule la première sous-chaîne trouvée est remplacée. La valeur de paramètre n’est pas modifiée. Caractères et expressions génériques peuvent être présents dans mod.

    Ce mécanisme de remplacement comprend plusieurs aspects :

    1. Remplacement de la première occurrence

      $ v=totito
      $ echo ${v/to/lo}
      lotito
      $

      La valeur de la variable v (totito) contient deux occurrences du modèle to. Seule la première occurrence est remplacée par la chaîne lo.

      $ set topo
      $ echo $1
      topo
      $
      $ echo ${1/o/i}
      tipo
      $

    2. Remplacement de la plus longue sous-chaîne

      $ v=abcfefg
      $ v1=${v/b*f/toto}   => utilisation du caractère générique *
      $ echo $v1
      atotog
      $

      Deux sous-chaînes de v satisfont le modèle b*f : bcf et bcfef

      C’est la plus longue qui est remplacée par toto.

  • ${paramètre//mod/ch} 

    Contrairement à la syntaxe précédente, toutes les occurrences (et non seulement la première) satisfaisant le modèle mod sont remplacées par la chaîne ch

    $ var=tobatoba
    $ echo ${var//to/tou}
    toubatouba
    $
    $ set topo
    $ echo $1
    topo
    $
    $ echo ${1//o/i}
    tipi
    $

  • ${paramètre//mod/} 

    Lorsque la chaîne ch est absente, la première ou toutes les occurrences (suivant la syntaxe utilisée) sont supprimées

    $ v=123azer45ty
    $ shopt –s extglob
    $ echo ${v//+([[:lower:]])/}
    12345
    $

    L’expression générique +([[:lower:]] désigne la plus longue suite non vide de minuscules. La syntaxe utilisée signifie que toutes les occurrences doivent être traitées : la variable v contient deux occurrences (azer et ty). Le traitement à effectuer est la suppression.

    Il est possible de préciser si l’on souhaite l’occurrence cherchée en début de chaîne de paramètre (syntaxe à utiliser : #mod) ou bien en fin de chaîne (%mod).

    $ v=automoto
    $ echo ${v/#aut/vel}
    velomoto
    $
    $ v=automoto
    $ echo ${v/%to/teur}
    automoteur
    $