| edix_shell_chaines(7f) | edix_shell_chaines(7f) |
NOM
edix_shell_chaines - La gestions des chaines de caractères en shell
DESCRIPTION
Le shell est fondamentallement appuyé sur le concept de chaine de caractères (voir edix_shell(7f)). Le nombre des gestes permis par le shell, pour la manipulation des chaines de caractères, est presque infini. Une bonne pratique du shell exige un investissement sérieux : vous devez vous former à la manipulation des chaines de caractères !
Ici, nous ne cherchons pas à remplacer cette formation. Il s'agit seulement d'indiquer quelques pistes de travail à partir de certains des gestes dont vous aurez le plus besoin dans vos travaux pratiques sous edix.
LES CHAINES, LES MOTS ET LES SEPARATEURS
Une chaine est une suite de caractères, y compris les caractères utilisés pour séparer des mots que l'on appelle les séparateurs. Usuellement, les séparateurs sont
- l'espace ;
- la tabulation \t;
- le saut de ligne \n.
etudiant:~ $ set | grep ^IFS=
qui doit renvoyer
IFS=$' \t\n'
Une chaine de caractères placée entre deux ' ou deux " est vue comme un seul mot.
Les idées importantes sont donc les suivantes :
- avec le concept de chaine de caractères, avant interprétation par le shell, les séparateurs sont des caractères comme les autres ;
- le shell peut interprèter une chaine de caractères comme une succession de mots en utilisant les séparateurs pour découper la chaine en mots ;
- en plaçant une chaine de caractères entre deux ' ou deux " on demande au shell de ne pas interpréter les séparateurs présents dans la chaine.
Exemple 1
etudiant:~ $ printf "%s\n" a bb cccc
produit
a
bb
cccc
Exemple 2
etudiant:~ $ printf "%s\n" 'a bb' cccc
produit
a bb
cccc
Exemple 3
etudiant:~ $ printf "%s\n" 'a bb' cccc "dd eee"
produit
a bb
cccc
dd eee
LES VARIABLES
En shell, comme dans tous les langages de programmation, il est possible de définir des variables. Le contenu d'une variable est une chaine de caractères. Par exemple, pour créer une variable nommée var1 et contenant la chaine de caractère 'abc defg h', ainsi qu'une variable nommée var2 contenant la chaine de caractère 'uu vvvv z', on peut saisir les commandes suivantes :
etudiant:~ $ var1='abc defg h' etudiant:~ $ var2='uu vvvv z'
var1 et var2 sont les noms des deux variables. On accède au contenu de var1 avec ${var1} et au contenu de var2 avec ${var2}.
On peut donc afficher le contenu des variable var1 et var2 avec la commande printf suivante :
etudiant:~ $ printf "%s\n" ${var1} ${var2}
qui produit
abc
defg
h
uu
vvvv
z
On voit que var1 contient une chaine de caractères qui contient deux caractères espace et que la commande printf interprète ces deux espaces comme des spérateurs de mots. Il en va de même pour var2. Elle affiche donc six mots.
Si on place ${var1} et ${var2} chacun entre deux ", alors la commande printf n'interprète pas les deux espace. Le contenu de var1 est vu comme un seul mot et le contenu de var2 est vu comme un seul mot. Ainsi la commande printf voit deux mots :
etudiant:~ $ printf "%s\n" "${var1}" "${var2}"
produit
abc defg h
uu vvvv z
Si on place ${var1} et ${var2} ensemble entre deux ", alors la commande printf ne voit plus qu'un seul mot :
etudiant:~ $ printf "%s\n" "${var1} ${var2}"
produit
abc defg h uu vvvv z
Si on place ${var1} et ${var2} ensemble entre deux ', alors la chaine de caractère entre les deux ' est vue comme un seul mot, mais ${var1} et ${var2} ne sont pas interprétés :
etudiant:~ $ printf "%s\n" '${var1} ${var2}'
produit
${var1} ${var2}
LES FICHIERS TEXTE
Une chaine de caractères peut être placée dans un fichier texte. Par exemple, la commande suivante crée le fichier /tmp/test.txt qui contient la chaine a bb cccc dd eee :
etudiant:~ $ printf "%s\n" 'a bb cccc dd eee' > /tmp/test.txt
Réciproquement, si on sait que le fichier /tmp/test.txt contient une chaine de caractères, on peut l'afficher avec la commande suivante :
etudiant:~ $ cat /tmp/test.txt
On peut aussi écrire cette chaine de caractères dans une variable du shell nommée var1 avec la commande suivante :
etudiant:~ $ var1=$(cat /tmp/test.txt)
RQ: Cette dernière commande illustre le sens du motif $( commande ) : la commande est exécutée et $( commande ) est remplacé par la chaine de caractère qu'a produit la commande sur la sortie standard.
LES VARIABLES POSITIONNELLES
Les noms de variables 1, 2, 3, etc, sont reservés au passage de chaines de caractères en entrée des scripts shell (voir edix_shell_script(7f)). On les appelle variables positionnelles. La variables # contient le nombre de variables positionnelles définies. Par exemple, la commande
etudiant:~ $ set a 'bb cccc' dd eee
définit quatre variables positionnelles, 1 qui contient $a$, 2 qui contient bb cccc, 3 qui contient dd et 4 qui contient eee. On peut les afficher avec
etudiant:~ $ printf "%s\n" "${1}"
etudiant:~ $ printf "%s\n" "${2}"
etudiant:~ $ printf "%s\n" "${3}"
etudiant:~ $ printf "%s\n" "${4}"
On peut vérifier que le nombre de variables positionnelles est bien 4 avec
etudiant:~ $ printf "%s\n" "${#}"
La variables * regroupe l'ensemble des variables positionnelles au sein d'une seule chaine de caractères. La commande
etudiant:~ $ printf "%s\n" ${*}
produit donc
a
bb
cccc
dd
eee
et la commande
etudiant:~ $ printf "%s\n" "${*}"
produit
a bb cccc dd eee
On voit ici qu'avec la variable * on perd l'information que bb et cccc étaient initialement associés pour ne former qu'un seul mot dans la variable 2.
On peut retrouver cette information dans la variables @ qui regroupe toutes les variables positionnelles, comme la variables *, mais conserve l'information sur le découpage en mots propre aux variables positionnelles. La commande
etudiant:~ $ printf "%s\n" ${@}
produit toujours
a
bb
cccc
dd
eee
mais la commande
etudiant:~ $ printf "%s\n" "${@}"
produit
a
bb cccc
dd
eee
EDITION DU CONTENU D'UNE VARIABLE
Dans les exemples, on travaille sur une chaine de nommée var1 dont le contenu est a bb cccc eee.
Il sera question de "modèles". Un modèle définit un sous-ensemble de toutes les chaines de caractères possibles. Par exemple le modèle * est le plus englobant de tous les modèles : il signifie "n'importe quelle chaine de caractères".
D'autres exemples sont
- a* est "l'ensemble de toutes les chaines de caractères commençant par a" ;
- *e est "l'ensemble de toutes les chaines de caractères se terminant par e".
Longueur de la chaine de caractère
${#var1} est une chaine de caractères qui contient la longueur de la chaine de caractères contenue dans la variable var1.
La commande
etudiant:~ $ printf "%s\n" ${#var1}
produit donc
13
qui est bien la longueur de la chaine de caractères a bb cccc eee (caractères espace y compris).
Réduction par la gauche de la plus petite sous-chaine correspondant au motif
${var1#modèle} correspond à la chaine de caractères contenue dans var1 à laquelle on enlève, au début (à gauche), la plus petite partie (la plus petite sous-chaine) correspondant au modèle.
Dans notre exemple var1 contient a bb cccc dd eee. Utilisons le modèle *b. La plus petite chaine à gauche correspondant à ce modèle est a b. En la supprimant de la chaine initiale on obtient b cccc dd eee. C'est donc ce que renvoit ${var1#*b}. Donc la commande
etudiant:~ $ printf "%s\n" "${var1#*b}"
produit
b cccc dd eee
Réduction par la gauche de la plus grande sous-chaine correspondant au motif
${var1##modèle} est identique, mais on enlève cette fois la plus grande sous-chaine correspondant au modèle : la commande
etudiant:~ $ printf "%s\n" "${var1##*b}"
produit
cccc dd eee
Réduction par la droite de la plus petite sous-chaine correspondant au motif
${var1%modèle} est comme ${var1#modèle} mais on cherche enlève la sous-chaine à partir de la droite : la commande
etudiant:~ $ printf "%s\n" "${var1%b*}"
produit
a b
Réduction par la droite de la plus grande sous-chaine correspondant au motif
${var1%%modèle} est comme ${var1##modèle} mais on cherche enlève la sous-chaine à partir de la droite : la commande
etudiant:~ $ printf "%s\n" "${var1%%b*}"
produit
a
Extraction d'une sous-chaine
Si a est un entier compris entre 0 et la longueur de la chaine, et si b est un entier positif tel que a+b est inférieur à la longueur de la chaine, alors ${var1:a:b} est la sous-chaine entre le a-ième et le (a+b)-ième caractère. Par exemple
etudiant:~ $ printf "%s\n" "${var1:0:16}"
produit
a bb cccc dd eee
c'est à dire la chaine intégrale (car 16 est la longueur de la chaine).
Autre exemple :
etudiant:~ $ printf "%s\n" "${var1:6:5}"
produit
ccc d
SED
etudiant:~ $ sed 1d articles_edstar.html > articles_edstar.md
etudiant:~ $ sed 's/^....//' fichier
VOIR AUSSI
edix_shell(7f)
| 2026-05-17 | UNIX |