L'opérateur $ sert habituellement à utiliser les variables déclarées :
maVariable="valeur" echo $maVariable # Affiche 'valeur'
Mais nous allons voir que le $ est d'une grande richesse1) pour la manipulation des chaînes.
Comme vous le savez sûrement, les accolades permettent d'afficher les variables de façon plus pratique, par exemple :
fichier="fichier" version="002" extension=".jpg" # Nous souhaitons obtenir un fichier sous la forme : # fichier_002.jpg echo $fichier_$version$extension # Affiche '.jpg'
En effet, l'interpréteur essai d'afficher la variable $fichier_ et pas $fichier suivit d'un underscore…
La solution passe par les accolades :
fichier="fichier"
version="002"
extension=".jpg"
echo ${fichier}_$version$extention
# Affiche '.jpg'
Le Bash permet de procéder à des extractions de chaînes par index.
Si vous êtes habitué au développement, la notion d'indexation des chaînes n'a pas de secret pour vous, pour les autres petit rappel.
Dans la plus part des langages, l'accès aux caractères d'une chaîne se fait par un système de numéro qui commence à zéro.
Par exemple la chaîne JACKSAY peut être représentée ainsi :
| J | A | C | K | S | A | Y |
|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 |
Si nous voulons extraire JACK de cette chaîne, vous allons demander à extraire de l'index 0 à l'index 3 (soit 4 indices extraits).
Pour découper des chaînes, on utilise l'opérateur ${} en utilisant les :, sa forme générique est :
${variable:indexDebut:taille}
Pour découper JACK dans la chaîne JACKSAY cela donne :
variable="JACKSAY"
echo ${variable:0:4}
# Affiche JACK
Bon les indices entre-nous c'est un peu merdique, donc nous allons nous orienter sur les motifs
L'idée est, comme son nom l'indique, de supprimer un morceau d'une chaîne de caractère. Pour faire ça on utilise le # sous la forme :
${variable#motif}
le # indique à Bash de découper la chaîne et de s'arrêter dès que le motif est trouvé. Cependant si le motif n'est pas trouvé, la chaîne restera intacte.
Un exemple simple :
#!/bin/bash
variable="Jack et un seul Jack"
echo ${variable#Jack}
# Affiche 'et un seul Jack'
Mais vous pouvez décrire le morceau de chaîne à extraire sous la forme d'un motif.
Les motifs ressemblent au expressions régulières.
L'idée d'un motif c'est d'exprimer une règle sous la forme "ressemble à", pour faire ça on utilise plusieurs combinaisons de caractères jockers
| Caractère | Effet |
|---|---|
| * | 0 à X caractères (y compris rien) |
| ? | N'importe quel caractère une seule fois |
Par exemple pour extraire l'extension d'un fichier :
fichier=paysage.jpg
echo ${paysage#*.}
# affiche 'jpg'
Sur cette exemple, il faut rappeler que la présence de . dans un nom de fichier n'est pas rare :
fichier="history.1.log"
echo ${fichier#*.}
# affiche '1.log'
Même principe, sauf que la découpe se fait sur le dernier motif trouvé
fichier="history.1.log"
echo ${fichier##*.}
# affiche '1.log'
L'utilisation du # ou du ## découpe le morceau de chaîne qui précède le motif (le préfixe).
Même principe mais inversé, le % et le %% vont procéder à la découpe, mais sur la portion de chaîne qui précède le motif. La recherche du motif commence par la fin.
fichier="history.1.log"
echo ${fichier%.*}
# affiche 'history.1'
# Motif extrait '.log'
et donc :
fichier="history.1.log"
echo ${fichier%%.*}
# affiche 'history'
# Motif extrait '.1.log'
Ce dernier est a priori le plus adapté pour extraire le nom d'un fichier débarrassé de son extension
Dernier utilisation (même si le sujet est loin d'être épuisé), la recherche et le remplacement de chaîne de caractère :
Cela se fait avec le / sous cette forme :
${variable/motifRecherché/remplacement}
Exemple
template="email@ma-societe.com"
user="jean.claude"
echo ${template/"email"/${user}}
# affiche 'jean.claude@ma-societe.com'