2012-05-18 7 views
9

quiero reemplazar todos los pares de corchetes en un archivo, por ejemplo, [some text], con \macro{some text}, por ejemplo:¿Cómo reemplazar los corchetes emparejados con otra sintaxis con sed?

This is some [text]. 
This [line] has [some more] text. 

esto se convierte en:

This is some \macro{text}. 
This \macro{line} has \macro{some more} text. 
  • Las parejas sólo se producen en las líneas individuales nunca a través de múltiples líneas.
  • A veces puede haber más de un par en una sola línea, pero nunca están anidados.
  • Si un soporte se encuentra solo en una línea, sin un par, entonces no se debe cambiar.

¿Cómo puedo reemplazar estos pares de soportes con este código?

Respuesta

6
sed -e 's/\[\([^]]*\)\]/\\macro{\1}/g' file.txt 

Esto busca un soporte de apertura, cualquier número de corchetes explícitamente sin cierre, luego un corchete de cierre. El grupo es capturado por los parens e insertado en la expresión de reemplazo.

2

La siguiente expresión coincide con el patrón [a-z, A-Z and space] y lo reemplaza con \macro{<whatever was between the []>}

sed -e 's/\[\([a-zA-Z ]*\)\]/\\macro{\1}/g' 

En la expresión la forma \(... \) un grupo partido que se puede hacer referencia más adelante en la sustitución como \1

+0

Esto puede ser correcto para los datos de prueba proporcionados, pero '[^]] *' encaja mejor. – potong

3

grupos de uso

sed 's|\[\([^]]*\)\]|\\macro{\1}|g' file 
21

tomó un poco de hacer, pero aquí:

sed -i.bkup 's/\[\([^]]*\)\]/\\macro{\1}/g' test.txt 

Vamos a ver si puedo explicar esta expresión regular:

  1. El \[ está haciendo juego un corchete. Como [ es un personaje de expresión regular mágico válido, la barra invertida significa que coincide con el carácter literal.
  2. El (...) es un grupo de captura. Captura la parte de la expresión regular que quiero. Puedo tener muchos grupos de captura, y en sed puedo hacer referencia a ellos como \1, \2, etc.
  3. Dentro del grupo de captura \(...\). Tengo [^]]*.
    1. La sintaxis [^...] significa cualquier caracter pero.
    2. El [^]] significa cualquier carácter excepto un corsé de cierre.
    3. El * significa cero o más de lo anterior. Eso significa que estoy capturando cero o más caracteres que no cierran llaves cuadradas.
  4. El \] significa que el corchete de cierre

Veamos la línea esto es [algunos] más [Texto]

  • En # 1 anterior, capturo la primera abrir el corchete delante de la palabra algunos. Sin embargo, no está en un grupo de captura. Este es el primer personaje que voy a sustituir.
  • Ahora comienzo un grupo de captura. Estoy capturando de acuerdo con 3.2 y 3.3 anteriores, comenzando con la letra s en algunos tantos caracteres como sea posible que no estén cerrando los corchetes. Esto significa que estoy haciendo coincidir [some, pero solo capturando some.
  • En el n. ° 4, he terminado mi grupo de captura. He emparejado con fines de sustitución [some y ahora estoy coincidiendo en el último corchete de cierre. Eso significa que estoy haciendo coincidir [some]. Tenga en cuenta que las expresiones regulares son normalmente codiciosas. Explicaré a continuación por qué esto es importante.
  • Ahora, puedo hacer coincidir la cadena de reemplazo. Esto es mucho más fácil. Es \\macro(\1). El \1 es reemplazado por mi grupo de captura. El \\ es solo una barra invertida. Por lo tanto, reemplazaré [some] con \macro{some}.

Sería mucho más fácil si pudiera garantizarse un solo conjunto de corchetes en cada línea. Entonces podría haber hecho esto:

sed -i.bkup 's/\[\(.*\)\]/\\macro(\1)/g' 

El grupo de captura ahora dice cualquier cosa entre corchetes. Sin embargo, el problema es que las expresiones regulares son codiciosas, eso significa que habría emparejado desde s en some hasta el final t en el texto. La 'x' a continuación muestra el grupo de captura. El [ y ] muestran los corchetes que estoy a juego en:

this is [some] more [text] 
     [xxxxxxxxxxxxxxxx] 

Esto se hizo más compleja, porque tenía que coincidir en los personajes que tenían un significado especial a las expresiones regulares, por lo que vemos una gran cantidad de backslashing. Además, tuve que dar cuenta de la codicia de expresión regular, que obtuvo la cadena [^]]* de aspecto agradable y sin coincidencia para que coincida con todo lo que no sea un corchete de cierre. Agregue los corchetes antes y después de \[[^]]*\], y no olvide el grupo de captura \(...\): \[\([^]]*\)\] Y obtiene un gran desorden de una expresión regular.

+0

¡Buena explicación! Sin embargo, el reemplazo debe estar rodeado por '\ macro {...}' – potong

+0

Corrección menor ... Editado mi respuesta. En una pantalla pequeña, a veces es difícil ver la diferencia entre '(' y '{'. –