J'ai vu cet exemple:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
Ce qui suit cette syntaxe: ${variable//pattern/replacement}
Malheureusement, le pattern
champ ne semble pas prendre en charge la syntaxe regex complète (si j'utilise .
ou \s
, par exemple, il essaie de faire correspondre les caractères littéraux).
Comment puis-je rechercher / remplacer une chaîne en utilisant la syntaxe regex complète?
\s
ne fait pas partie de la syntaxe d'expression régulière définie par POSIX (ni BRE ni ERE); c'est une extension PCRE, et la plupart du temps non disponible depuis le shell.[[:space:]]
est l'équivalent le plus universel.\s
peut être remplacé par[[:space:]]
, au fait,.
par?
, et les extensions extglob du langage de modèle de shell de base peuvent être utilisées pour des choses comme des sous-groupes facultatifs, des groupes répétés, etc.Réponses:
Utilisez sed :
Notez que les suivants
-e
sont traités dans l'ordre. De plus, l'g
indicateur de l'expression correspondra à toutes les occurrences de l'entrée.Vous pouvez également choisir votre outil préféré en utilisant cette méthode, c'est-à-dire perl, awk, par exemple:
Cela peut vous permettre de faire plus de correspondances créatives ... Par exemple, dans la capture ci-dessus, le remplacement numérique ne serait pas utilisé à moins qu'il y ait une correspondance sur la première expression (en raison d'une
and
évaluation paresseuse ). Et bien sûr, vous avez le support linguistique complet de Perl pour faire vos enchères ...la source
sed
ou d'autres outils externes est coûteuse en raison du temps d'initialisation du processus. J'ai particulièrement recherché une solution tout-bash, car j'ai trouvé que l'utilisation des substitutions bash était plus de 3 fois plus rapide que d'appelersed
chaque élément de ma boucle.Cela peut en fait être fait en pure bash:
... donne ...
la source
=~
C'est la clé. Mais un peu maladroit, vu la réaffectation dans la boucle. La solution @jheddings 2 ans avant est une autre bonne option - appeler sed ou perl).sed
ouperl
est judicieux, si vous utilisez chaque appel pour traiter plus d'une seule ligne d'entrée. Invoquer un tel outil à l'intérieur d'une boucle, par opposition à l'utilisation d'une boucle pour traiter son flux de sortie, est imprudent.$match
au lieu de$BASH_REMATCH
. (Vous pouvez le faire se comporter comme un bash avecsetopt bash_rematch
.)Ces exemples fonctionnent également dans bash sans avoir besoin d'utiliser sed:
vous pouvez également utiliser les expressions entre crochets de classe de caractères
production
Ce que @Lanaru voulait savoir cependant, si je comprends bien la question, c'est pourquoi les extensions "complètes" ou PCRE,
\s\S\w\W\d\D
etc. ne fonctionnent pas comme prises en charge dans php ruby python etc. peut ne pas être compatible avec d'autres formes d'expressions régulières basées sur un shell.Ceux-ci ne fonctionnent pas:
sortie avec tous les caractères littéraux "d" supprimés
mais ce qui suit fonctionne comme prévu
production
J'espère que cela clarifie un peu plus les choses, mais si vous n'êtes pas encore confus, pourquoi ne pas essayer ceci sur Mac OS X qui a le drapeau REG_ENHANCED activé:
Sur la plupart des versions de * nix, vous ne verrez que la sortie suivante:
nJoy!
la source
${foo//$bar/$baz}
n'est pas une syntaxe POSIX.2 BRE ou ERE - c'est une correspondance de modèle de style fnmatch ().${hello//[[:digit:]]/}
fonctionne, si nous voulions filtrer uniquement les chiffres précédés par la lettreo
,${hello//o[[:digit:]]*}
aurait un comportement entièrement différent de celui attendu (puisque dans les modèles fnmatch,*
correspond à tous les caractères, plutôt que de modifier l'élément immédiatement précédent pour être 0 ou plus).[0-9]
ou[[:digit:]]
Si vous effectuez des appels répétés et que vous êtes préoccupé par les performances, ce test révèle que la méthode BASH est environ 15 fois plus rapide que le passage à sed et probablement tout autre processus externe.
la source
Utilisez
[[:digit:]]
(notez les doubles crochets) comme motif:Je voulais juste résumer les réponses ( en particulier @ Nickl-de https://stackoverflow.com/a/22261334/2916086 ).
la source
Je sais que c'est un fil ancien, mais c'était mon premier succès sur Google, et je voulais partager ce
resub
qui suit que j'ai rassemblé, ce qui ajoute la prise en charge de plusieurs références inverses de 1 $, 2 $, etc.H / T à @Charles Duffy concernant :
(.*)$match(.*)
la source