He visto este ejemplo:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
Que sigue a esta sintaxis: ${variable//pattern/replacement}
Desafortunadamente, el pattern
campo no parece admitir la sintaxis de expresiones regulares completas (si uso .
o \s
, por ejemplo, intenta hacer coincidir los caracteres literales).
¿Cómo puedo buscar / reemplazar una cadena usando la sintaxis completa de expresiones regulares?
\s
no es parte de la sintaxis de expresión regular estándar definida por POSIX (ni BRE ni ERE); es una extensión PCRE, y en su mayoría no está disponible desde shell.[[:space:]]
Es el equivalente más universal.\s
puede ser reemplazado por[[:space:]]
, por cierto,.
por?
, y las extensiones extglob al lenguaje de patrón de shell de línea de base pueden usarse para cosas como subgrupos opcionales, grupos repetidos y similares.Respuestas:
Use sed :
Tenga en cuenta que los subsiguientes
-e
se procesan en orden. Además, elg
indicador de la expresión coincidirá con todas las apariciones en la entrada.También puede elegir su herramienta favorita utilizando este método, es decir, perl, awk, por ejemplo:
Esto puede permitirle hacer más coincidencias creativas ... Por ejemplo, en el recorte anterior, el reemplazo numérico no se usaría a menos que hubiera una coincidencia en la primera expresión (debido a una
and
evaluación diferida ). Y, por supuesto, tiene el soporte de idiomas completo de Perl para hacer su oferta ...fuente
sed
u otras herramientas externas es costoso debido al tiempo de inicialización del proceso. Especialmente busqué la solución all-bash, porque descubrí que usar sustituciones bash es más de 3 veces más rápido que llamarsed
a cada elemento de mi ciclo.Esto realmente se puede hacer en puro bash:
... rinde ...
fuente
=~
es la llave. Pero un poco torpe, dada la reasignación en el bucle. La solución @jheddings 2 años antes es otra buena opción: llamar a sed o perl).sed
operl
es sensato, si usa cada invocación para procesar más de una sola línea de entrada. Invocar dicha herramienta en el interior de un bucle, en lugar de usar un bucle para procesar su flujo de salida, es insensato.$match
lugar de$BASH_REMATCH
. (Puedes hacer que se comporte como una fiestasetopt bash_rematch
).Estos ejemplos también funcionan en bash sin necesidad de usar sed:
también puedes usar las expresiones de paréntesis de clase de caracteres
salida
Sin embargo, lo que @Lanaru quería saber, si entiendo la pregunta correctamente, es por qué las extensiones "completa" o PCRE,
\s\S\w\W\d\D
etc., no funcionan como se admite en php ruby python, etc. Estas extensiones son de expresiones regulares compatibles con Perl (PCRE) y puede no ser compatible con otras formas de expresiones regulares basadas en shell.Estos no funcionan:
salida con todos los caracteres literales "d" eliminados
pero lo siguiente funciona como se esperaba
salida
Espero que eso aclare un poco más las cosas, pero si aún no está confundido, ¿por qué no prueba esto en Mac OS X que tiene habilitado el indicador REG_ENHANCED?
En la mayoría de los sabores de * nix solo verá el siguiente resultado:
nJoy!
fuente
${foo//$bar/$baz}
es la sintaxis POSIX.2 BRE o ERE, es una coincidencia de patrones de estilo fnmatch ().${hello//[[:digit:]]/}
funciona, si quisiéramos filtrar solo los dígitos precedidos por la letrao
,${hello//o[[:digit:]]*}
tendría un comportamiento completamente diferente al esperado (ya que en patrones fnmatch,*
coincide con todos los caracteres, en lugar de modificar el elemento inmediatamente anterior para que sea 0 o más).[0-9]
o[[:digit:]]
Si realiza llamadas repetidas y le preocupa el rendimiento, esta prueba revela que el método BASH es ~ 15 veces más rápido que la bifurcación y probablemente cualquier otro proceso externo.
fuente
Use
[[:digit:]]
(observe los corchetes dobles) como patrón:Solo quería resumir las respuestas (especialmente @ nickl- 's https://stackoverflow.com/a/22261334/2916086 ).
fuente
Sé que este es un hilo antiguo, pero fue mi primer éxito en Google, y quería compartir lo siguiente
resub
que armé, lo que agrega soporte para múltiples referencias de $ 1, $ 2, etc.H / T a @Charles Duffy re:
(.*)$match(.*)
fuente