bash: Comment utiliser plusieurs manipulations de chaînes (expansion de paramètres) en une seule étape?
J'ai string=substr1-substr2-substr3.substr4
où les sous-chaînes sont de longueur variable. Je veux extraire substr3
de string
et je pense à le faire en utilisant les ${string##pattern}
et ${string%pattern}
extensions de manipulation de chaînes. En utilisant cette approche, il est clair que je dois exécuter ${string##*-}
et exécuter ${string%.*}
l'extension résultante, ou vice versa. Mes questions sont:
- est-ce le meilleur choix?
- Si oui, comment exécuter les deux en une seule étape? Quand j'essaye de faire quelque chose comme
${string##*-${string%.*}}
ou${string%.*${string##*-}}
je récupère juste la chaîne complète. Je me rends compte que je pourrais toujours faire l'extraction en deux étapes en attribuant une variable intermédiaire au résultat de la première étape, puis en la manipulant; mais je veux le faire en une seule étape. Comment dois-je procéder?
TIA!
Réponses
Donné
string=substr1-substr2-substr3.substr4
${string%.*}
est
substr1-substr2-substr3
alors, ${string##*-${string%.*}}
est
${string##*-substr1-substr2-substr3}
ce qui signifie supprimer dès le début de string
tout ce qui va jusqu'à et y compris -substr1-substr2-substr3
. Mais il n'y a pas de telle sous-chaîne string
, car il n'y a pas de tiret devant substr1
, vous obtenez donc la chaîne d'origine.
Ce que vous voulez probablement, c'est
string=substr1-substr2-substr3.substr4
result="${string%.*}" result="${result##*-}"
ce qui conduit à result
containg substr3
.
Dans Zsh, vous pouvez le faire en une seule étape:, mais cela ne fonctionne pas dans Bash.result=${${string%.*}##*-}
Dans Bash, vous êtes limité à l'utilisation d'extensions sur le côté droit de #
ou %
, et cela ne vous aide pas ici car vous devez supprimer des parties à la fois du début et de la fin de la chaîne.
Sinon, si $string
ne contient pas de caractères de nouvelle ligne, vous pouvez utiliser
IFS=.- read -r a b c d <<< "$string"
et lire substr3
à partir de c
.
Dans ce cas, en fonction du shell et de la taille de la chaîne, le contenu de $string
sera soit stocké dans un fichier temporaire, soit transmis via un tube qui read
lira la première ligne et la divisera en fonction de $IFS
.