2010-10-29 12 views
23

Estoy tratando de usar una expresión regular usando sed. He probado mi expresión regular con kiki, una aplicación gnome para probar regexpd, y funciona en kiki.¿Cómo se "depura" una expresión regular con sed?

date: 2010-10-29 14:46:33 -0200; author: 00000000000; state: Exp; lines: +5 -2; commitid: bvEcb00aPyqal6Uu; 

quiero reemplazar author: 00000000000; sin nada. Por lo tanto, he creado la expresión regular, que funciona cuando lo pruebo en kiki:

author:\s[0-9]{11}; 

pero no funciona cuando lo pruebo en sed.

sed -i "s/author:\s[0-9]{11};//g" /tmp/test_regex.txt 

Sé que regex tiene diferentes implementaciones, y este podría ser el problema. Mi pregunta es: ¿cómo puedo al menos intentar "depurar" lo que está sucediendo con sed? ¿Por qué no está funcionando?

+2

He encontrado que cuando se utiliza sed con una sustitución y desea depurar la parte "buscar", primero ayuda a obtener la expresión regular en grep. Debido a que grep deja en claro si coincide o no, puede solucionar problemas, y puede eliminar desde el lado derecho hasta que coincida y solucionar problemas de compilación, viendo lo que coincide. Podrías usar otra herramienta para probar, veo que usaste una llamada kiki. ¿Qué hay de usar grep, puede encontrar que con el interruptor derecho y sed, obtiene la misma implementación. como GNU ERE o algo así. – barlop

+0

Ver también: https://regex101.com/ –

Respuesta

14

A mi versión de sed no le gusta el bit {11}. Procesando la línea con:

sed 's/author: [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9];//g' 

funciona bien.

Y la forma en que lo depuro es exactamente lo que hice aquí. Yo sólo construyó un comando:

echo 'X author: 00000000000; X' | sed ... 

y quitó el más avanzado de expresiones regulares una cosas a la vez:

  • <space> utilizarse en lugar de \s, no solucionarlo.
  • reemplazó [0-9]{11} con 11 copias de [0-9], funcionó.

Es más o menos tenía que ser uno de los que ya he utilizado todas las otras características de la expresión regular anterior con sed éxito.

Pero, de hecho, esto se en realidad el trabajo sin los horribles 11 copias de [0-9], sólo tienes que escapar de los apoyos [0-9]\{11\}. Tengo que admitir que no intenté eso porque funcionó bien con los múltiplos y generalmente no me preocupo demasiado por la brevedad en sed, ya que tiendo a usarlo más para trabajos rápidos y sin trabajo:)

Pero el método de abrazadera es mucho más conciso y adaptable y es bueno saber cómo hacerlo.

+0

Creo que dejarlo como espacio también lo ayudó. –

+3

Intenté escapar '{' y '}': sed -i "s/autor: \ s [0-9] \ {11 \}; // g" /tmp/test_regex.txt. Funcionó. ¿Te importaría probar? –

+0

@ Peer, en realidad, lo puse de nuevo y funcionó.Eso no quiere decir que funcionará en _every_ 'sed' (el mío es el de CygWin). – paxdiablo

0

El hecho de que se está sustituyendo author: 00000000000 ya se ha dicho en sed cuando se agrega el s antes de la primera /.

+0

Pero no está funcionando. autor: 00000000000 no se sustituye con la línea que proporcioné. –

+0

¿Qué no está funcionando? No proporcioné un ejemplo, sino una respuesta sobre por qué tu expresión regular no funcionó. En la respuesta de paxdiablo encontrarás el comando correcto para sed. –

+0

autor: 00000000000 no se sustituye, por lo que la expresión regular no funciona. Gracias de cualquier manera. –

2

Está utilizando el distintivo -i incorrectamente. Debes ponerle una cuerda para poner en el archivo temporal. También necesitas escapar de tus llaves.

sed -ibak -e "s/author:\s[0-9]\{11\};//g" /tmp/test_regex.txt 

lo general depurar mi declaración a partir de una expresión regular sé que van a trabajar (como 's/autor // g' en este caso). Cuando eso funciona, sé que tengo los argumentos correctos. Luego amplío la expresión regular de forma incremental.

+0

Probé con \ {en la respuesta de paxdiablo. Está funcionando, solo quería saber si también funcionará en su entorno. Entendí también el enfoque incrementalmente regex de paxdiablo, seens para ser uno bueno. –

+1

'-i' no _necesita_ un sufijo y, cuando lo usa, es' -ibak' o '--in-place = bak', nunca' -i = bak'. No voy a menospreciar ya que es trivial, pero es posible que desee arreglarlo. – paxdiablo

+0

se arregló el sufijo -i, la antigua funciona bien, simplemente pone algunos caracteres adicionales en el sufijo. Hay algunas versiones de sed que no crearán un archivo temporal si no proporciona un sufijo. Esto es peligroso y puede causar daños en los datos. –

19

En sed necesita escapar de las llaves. "s/author:\s[0-9]\{11\};//g" debería funcionar.

Sed no tiene capacidad de depuración. Para probarlo, simplifique en la línea de comando de forma iterativa hasta que obtenga algo para funcionar y luego cree una copia de seguridad.

comando de entrada de línea:

$ echo 'xx a: 0b: 5432' | sed -e 's/a:\s[0-9]\{5\}//' 

comando de salida de línea:

xx b: 5432 
+0

¡El software de publicación se comió mis pestañas inversas! Coloque una barra invertida antes de abrir y cerrar llaves. – verisimilidude

+2

He solucionado tu respuesta. Si coloca marcadores en el código, lo dejará en paz (primera línea arriba). Si aplica sangría a líneas con cuatro espacios, obtendrá el mismo efecto para los bloques de códigos (sección inferior). – paxdiablo

2

Eso se parece más a una expresión regular Perl que lo hace una expresión regular sed. Si lo prefiere el uso de

perl -pi.orig -e 's/author:\s[0-9]{11};//g' file1 file2 file3 

Al menos de esa manera siempre se puede añadir -Mre=debug para depurar la expresión regular.

14

Hay un script de Python llamado sedsed por Aurelio Jargas que mostrará la ejecución paso a paso de un script sed. Un depurador como este no va a ayudar mucho en el caso de caracteres tomados literalmente (ej. {) versus tener un significado especial (ej. \{), especialmente para una sustitución simple, pero ayudará cuando se esté depurando un script más complejo .

The latest SVN version.
The most recent stable release.
Descargo de responsabilidad: Soy un colaborador menor de sedsed.

sedsed example

Otra sed depurador, sd por Brian Hiles, escrito como una secuencia de comandos shell Bourne (no he usado éste).

10

usted tiene que utilizar la opción -r para la expresión regular extendida:

sed -r 's/author:\s[0-9]{11};//g' 

o tiene que escapar los caracteres {}:

sed 's/author:\s[0-9]\{11\};//g' 
+1

'sed -r' es también mi opción favorita: más claro para leer los patrones como paréntesis y muchos otros tienen que escaparse de lo contrario ... –

Cuestiones relacionadas