2011-03-16 16 views
7

Necesito egrep una cadena que no se conoce antes del tiempo de ejecución y que obtendré a través de la variable de shell (shell es bash, si eso importa). El problema es que esa cadena contendrá caracteres especiales como llaves, espacios, puntos, barras, etc.¿Cómo escapar de una cadena previamente desconocida en la expresión regular?

Si conozco la cadena puedo escapar de los caracteres especiales de a uno por vez, pero ¿cómo puedo hacer eso para toda la cadena?

Ejecutar la cadena a través de una secuencia de comandos sed para prefijar cada carácter especial con \ podría ser una idea, todavía tengo que recordar cómo se debe escribir una secuencia de comandos. No sé si hay otras opciones mejores.

leí re_format(7) pero parece que no hay tal cosa como "tomar toda la siguiente cadena literal" ...

EDIT: para evitar falsos positivos, También me gustaría añadir la detección de nueva línea con el patrón, p.ej. egrep '^myunknownstring'

+0

cómo escapar de las expresiones regulares en bash http://stackoverflow.com/questions/11856054/bash-easy-way-to-pass-a-raw-string-to-grep/16951928#16951928 –

Respuesta

7

Si necesita integrar la cadena en una expresión mayor, sed es la forma en que lo haría.

s_esc="$(echo "$s" | sed 's/[^-A-Za-z0-9_]/\\&/g')" # backslash special characters 
inv_ent="$(egrep "^item [0-9]+ desc $s_esc loc .+$" inventory_list)" 
+0

Pruebe 'sed 's/[^ [: alnum:] _-]/\\ &/g'' en su lugar porque su versión no funciona en todas las configuraciones regionales – SiegeX

+0

' s_esc = $ (echo "$ s" | sed' s/[] \\. $ * {} | +?() [^ -]/\\ &/g ') 'también debería funcionar. – skozin

4

usar la bandera -F Para que el patrón de una cadena literal fija

$ var="(.*+[a-z]){3}" 
$ echo 'foo bar (.*+[a-z]){3} baz' | grep -F "$var" -o 
(.*+[a-z]){3} 
+0

gracias por la sugerencia , eso es correcto, pero olvidé especificar que también necesito unir la cadena _only_ al comienzo de la línea. Agregué este detalle a la pregunta. – Luke404

0

¿Estás tratando de proteger a la cadena sean interpretados incorrectamente como sintaxis bash o estás tratando de proteger las partes de la cadena de ser interpretado como sintaxis de expresiones regulares?

Para la protección bash:

grep soporta el interruptor -f:

-f FILE, --file=FILE 
    Obtain patterns from FILE, one per line. The empty file contains zero patterns, and therefore matches nothing. 

hay escape es necesaria dentro del archivo. Simplemente conviértalo en un archivo que contenga una sola línea (y, por lo tanto, un patrón) que se puede producir a partir de la variable de su caparazón si eso es lo que debe hacer.

# example trivial regex 
var='^r[^{]*$' 
pattern=/tmp/pattern.$$ 
rm -f "$pattern" 
echo "$var" > "$pattern" 
egrep -f "$pattern" /etc/password 
rm -f "$pattern" 

Solo para ilustrar el punto.

Probarlo con -F en su lugar como otro cartel sugerido para la protección de expresiones regulares.

Cuestiones relacionadas