Dans mon bash
script, j'ai une chaîne et son préfixe / suffixe. J'ai besoin de 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 arriver au résultat suivant?
result="o-wor"
Réponses:
la source
${${string#prefix}%suffix}
mais ça ne marche pas.Utilisation de sed:
Dans la commande sed, le
^
caractère correspond au texte commençant par$prefix
et le dernier$
correspond au texte se terminant par$suffix
.Adrian Frühwirth fait quelques bons points dans les commentaires ci-dessous, mais
sed
à cet effet peut être très utile. Le fait que le contenu de $ prefix et $ suffix soit interprété par sed peut être bon OU mauvais - tant que vous y prêtez attention, ça devrait aller. La beauté est que vous pouvez faire quelque chose comme ça:qui peut être ce que vous voulez, et est à la fois plus sophistiqué et plus puissant que la substitution de variables bash. Si vous vous souvenez qu'avec une grande puissance vient une grande responsabilité (comme le dit Spiderman), tout va bien.
Une introduction rapide à sed peut être trouvée à http://evc-cit.info/cit052/sed_tutorial.html
Une note concernant le shell et son utilisation des cordes:
Pour l'exemple particulier donné, les éléments suivants fonctionneraient également:
... 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 comme un seul argument. Nous citons $ prefix et $ suffix pour la même raison: chaque commande d'édition à sed sera passée comme 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 un littéral
$prefix
et$suffix
ce n'est certainement pas ce que nous voulions.Notez également mon utilisation de guillemets simples lors de la définition des variables
prefix
etsuffix
. Nous ne voulons certainement pas que quoi que ce soit dans les chaînes soit interprété, nous les citons donc pour qu'aucune interpolation n'ait lieu. Encore une fois, cela peut ne pas être nécessaire dans cet exemple, mais c'est une très bonne habitude à prendre.la source
$string
est sujet au fractionnement et à la globalisation des mots. 2)$prefix
et$suffix
peut contenir des expressions quised
interpréteront, par exemple des expressions régulières ou le caractère utilisé comme délimiteur qui cassera toute la commande. 3) Ilsed
n'est pas nécessaire d' appeler deux fois (vous pouvez à la-e 's///' -e '///'
place) et le tuyau peut également être évité. Par exemple, considérezstring='./ *'
et / ouprefix='./'
et voyez-le se briser horriblement à cause de1)
et2)
./
, alors j'ai utilisé à lased "s#^$prefix##
place. (Fragilité: les noms de fichiers ne peuvent pas contenir#
. Puisque je contrôle les fichiers, nous sommes en sécurité, là-bas.)#
comme délimiteur de sed signifiait que vous ne pouviez pas gérer les fichiers contenant ce caractère.Connaissez-vous la longueur de votre préfixe et suffixe? Dans ton cas:
Ou plus général:
Mais la solution d'Adrian Frühwirth est bien cool! Je n'en savais rien!
la source
J'utilise grep pour supprimer les préfixes des chemins (qui ne sont pas bien gérés par
sed
):\K
supprime de la correspondance tous les caractères précédents.la source
grep -P
est une extension non standard. Plus de puissance pour vous si elle est prise en charge sur votre plate-forme, mais c'est un conseil douteux si votre code doit être raisonnablement portable.grep
. Les versions antérieures avaient en fait l'-P
option de BSDgrep
mais elles l'ont supprimée.Remarques:
# $ prefix: l'ajout de # garantit que la sous-chaîne "hell" n'est supprimée que si elle est trouvée au début. % $ suffixe: l'ajout de% garantit que la sous-chaîne "ld" n'est supprimée que si elle est trouvée à la fin.
Sans cela, les sous-chaînes "hell" et "ld" seront supprimées partout, même si elles se trouvent au milieu.
la source
/
juste après la chaîne, à quoi cela sert-il?Utilisation de l'
=~
opérateur :la source
Solution petite et universelle:
la source
expr
du tout. C'était une sorte d' utilité pratique pour l'évier de cuisine à l'époque de la coque Bourne d'origine, mais elle a désormais dépassé sa date de péremption.Utilisation de la réponse @Adrian Frühwirth:
l'utiliser comme ça
la source
Je voudrais utiliser des groupes de capture dans regex:
((?:(?!(${suffix})).)*)
s'assure que le contenu de${suffix}
sera exclu du groupe de capture. En termes d'exemple, c'est la chaîne équivalente à[^A-Z]*
. Sinon, vous obtiendrez:la source