Dans mon script bash
, j'ai une chaîne et son préfixe/suffixe. Je dois supprimer le préfixe/suffixe de la chaîne d'origine.
Par exemple, supposons que j'ai les valeurs suivantes:
string="hello-world"
prefix="hell"
suffix="ld"
Comment puis-je arriver au résultat suivant?
result="o-wor"
$ foo=${string#"$prefix"}
$ foo=${foo%"$suffix"}
$ echo "${foo}"
o-wor
Utilisation de sed:
_$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor
_
Dans la commande sed, le caractère _^
_ correspond au texte commençant par _$prefix
_, et le point final _$
_ correspond au texte se terminant par _$suffix
_.
Adrian Frühwirth fait quelques bons points dans les commentaires ci-dessous, mais sed
peut être très utile à cet effet. Le fait que sed interprète les contenus de $ prefix et $ suffix peut être bon OR mauvais- tant que vous y prêtez attention, tout va bien. La beauté est, vous pouvez faire quelque chose comme ça:
_$ prefix='^.*ll'
$ suffix='ld$'
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor
_
ce qui peut être ce que vous voulez, et est à la fois plus sophistiqué et plus puissant que la substitution variable bash. Si vous vous souvenez que, avec un grand pouvoir, de grandes responsabilités (comme le dit Spiderman), ça devrait aller.
Vous trouverez une brève introduction à sed à l’adresse http://evc-cit.info/cit052/sed_tutorial.html
Une note concernant le Shell et son utilisation de chaînes:
Pour l'exemple donné, les éléments suivants fonctionneraient également:
_$ echo $string | sed -e s/^$prefix// -e s/$suffix$//
_
... mais uniquement parce que:
Il est généralement recommandé de citer une chaîne sur la ligne de commande, car même si elle contient des espaces, elle sera présentée à la commande sous la forme d'un argument unique. Nous citons $ prefix et $ suffix pour la même raison: chaque commande de modification à sed sera transmise sous la forme d'une chaîne. Nous utilisons des guillemets doubles car ils permettent une interpolation variable; Si nous avions utilisé des guillemets simples, la commande sed aurait obtenu les valeurs littérales _$prefix
_ et _$suffix
_, ce qui n'est certainement pas ce que nous voulions.
Remarquez aussi mon utilisation de guillemets simples lors de la définition des variables prefix
et suffix
. Nous ne voulons certainement pas que les chaînes soient interprétées. Nous les citons donc seules afin d'éviter toute interpolation. Encore une fois, cela n’est peut-être pas nécessaire dans cet exemple, mais c’est une très bonne habitude à prendre.
Connaissez-vous la longueur de votre préfixe et suffixe? Dans ton cas:
result=$(echo $string | cut -c5- | rev | cut -c3- | rev)
Ou plus général:
result=$(echo $string | cut -c$((${#prefix}+1))- | rev | cut -c$((${#suffix}+1))- | rev)
Mais le solution d'Adrian Frühwirth est vraiment cool! Je ne savais pas à ce sujet!
J'utilise grep pour supprimer les préfixes des chemins (qui ne sont pas bien gérés par sed
):
echo "$input" | grep -oP "^$prefix\K.*"
\K
supprime de la correspondance tous les caractères précédents.
$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ #remove "hell" from "hello-world" if "hell" is found at the beginning.
$ prefix_removed_string=${string/#$prefix}
$ #remove "ld" from "o-world" if "ld" is found at the end.
$ suffix_removed_String=${prefix_removed_string/%$suffix}
$ echo $suffix_removed_String
o-wor
# $ préfixe: ajouter # permet de s'assurer que la sous-chaîne "hell" est supprimée uniquement si elle est trouvée au début. % $ suffixe: ajouter% permet de s'assurer que la sous-chaîne "ld" est supprimée uniquement si elle se trouve dans end.
Sans cela, les sous-chaînes "hell" et "ld" seront supprimées partout, même si elles se trouvent au milieu.
Solution petite et universelle:
expr "$string" : "$prefix\(.*\)$suffix"
Utilisation de l'opérateur =~
) :
$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ [[ "$string" =~ ^$prefix(.*)$suffix$ ]] && echo "${BASH_REMATCH[1]}"
o-wor
En utilisant @Adrian Frühwirth, répondez:
function strip {
local STRING=${1#$"$2"}
echo ${STRING%$"$2"}
}
l'utiliser comme ça
HELLO=":hello:"
HELLO=$(strip "$HELLO" ":")
echo $HELLO # hello