Editor de transmisiones: cadenas

Comando sustituto

Las operaciones de sustitución de texto como "buscar y reemplazar" son comunes en cualquier editor de texto. En esta sección, ilustramos cómo SED realiza la sustitución de texto. A continuación se muestra la sintaxis del comando de sustitución.

[address1[,address2]]s/pattern/replacement/[flags]

Aquí, address1 y address2son las direcciones inicial y final respectivamente, que pueden ser números de línea o cadenas de patrones. Ambas direcciones son parámetros opcionales. El patrón es el texto que queremos reemplazar con la cadena de reemplazo. Además, podemos especificar banderas opcionales con el SED.

En el archivo books.txt, hemos utilizado una coma (,) para separar cada columna. Usemos una barra vertical (|) para separar cada columna. Para hacer esto, reemplace la coma (,) con la barra vertical (|).

[jerry]$ sed 's/,/ | /' books.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

1) A Storm of Swords | George R. R. Martin, 1216 
2) The Two Towers | J. R. R. Tolkien, 352 
3) The Alchemist | Paulo Coelho, 197 
4) The Fellowship of the Ring | J. R. R. Tolkien, 432 
5) The Pilgrimage | Paulo Coelho, 288 
6) A Game of Thrones | George R. R. Martin, 864

Si observa con atención, solo se reemplaza la primera coma y la segunda permanece como está. ¿Por qué? Tan pronto como el patrón coincida, SED lo reemplaza con la cadena de reemplazo y pasa a la siguiente línea. De forma predeterminada, reemplaza solo la primera aparición. Para reemplazar todas las ocurrencias, use la bandera global (g) con SED de la siguiente manera:

[jerry]$ sed 's/,/ | /g' books.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

1) A Storm of Swords | George R. R. Martin | 1216 
2) The Two Towers | J. R. R. Tolkien | 352 
3) The Alchemist | Paulo Coelho | 197 
4) The Fellowship of the Ring | J. R. R. Tolkien | 432 
5) The Pilgrimage | Paulo Coelho | 288 
6) A Game of Thrones | George R. R. Martin | 864

Ahora todas las apariciones de comas (,) se reemplazan con una barra vertical (|).

Podemos indicarle al SED que realice la sustitución de texto solo cuando una coincidencia de patrón tenga éxito. El siguiente ejemplo reemplaza la coma (,) con la barra vertical (|) solo cuando una línea contiene el patrón The Pilgrimage.

[jerry]$ sed '/The Pilgrimage/ s/,/ | /g' books.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

1) A Storm of Swords, George R. R. Martin, 1216 
2) The Two Towers, J. R. R. Tolkien, 352 
3) The Alchemist, Paulo Coelho, 197 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
5) The Pilgrimage | Paulo Coelho | 288 
6) A Game of Thrones, George R. R. Martin, 864

Además de esto, SED puede reemplazar una ocurrencia específica del patrón. Reemplacemos solo la segunda instancia de coma (,) con barra vertical (|).

[jerry]$ sed 's/,/ | /2' books.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

1) A Storm of Swords, George R. R. Martin | 1216 
2) The Two Towers, J. R. R. Tolkien | 352 
3) The Alchemist, Paulo Coelho | 197 
4) The Fellowship of the Ring, J. R. R. Tolkien | 432 
5) The Pilgrimage,Paulo Coelho | 288 
6) A Game of Thrones, George R. R. Martin  | 864

En el ejemplo anterior, el número al final del comando SED (o en el lugar de la bandera) implica la segunda aparición.

SED proporciona una característica interesante. Después de realizar la sustitución, SED ofrece una opción para mostrar solo las líneas cambiadas. Para este propósito, SED utiliza elpbandera que se refiere a la impresión. El siguiente ejemplo enumera solo las líneas modificadas.

[jerry]$ sed -n 's/Paulo Coelho/PAULO COELHO/p' books.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

3) The Alchemist, PAULO COELHO, 197 
5) The Pilgrimage, PAULO COELHO, 288

También podemos almacenar líneas cambiadas en otro archivo. Para lograr este resultado, utilice elwbandera. El siguiente ejemplo muestra cómo hacerlo.

[jerry]$ sed -n 's/Paulo Coelho/PAULO COELHO/w junk.txt' books.txt

Usamos el mismo comando SED. Verifiquemos el contenido deljunk.txt archivo.

[jerry]$ cat junk.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

3) The Alchemist, PAULO COELHO, 197 
5) The Pilgrimage, PAULO COELHO, 288

Para realizar una sustitución que no distingue entre mayúsculas y minúsculas, utilice la bandera i que implica ignorar las mayúsculas y minúsculas. El siguiente ejemplo realiza una sustitución que no distingue entre mayúsculas y minúsculas.

[jerry]$ sed  -n 's/pAuLo CoElHo/PAULO COELHO/pi' books.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

3) The Alchemist, PAULO COELHO, 197 
5) The Pilgrimage, PAULO COELHO, 288

Hasta ahora, hemos usado solo el carácter de barra (/) como delimitador, pero también podemos usar la barra vertical (|), el signo (@), el símbolo de intercalación (^), el signo de exclamación (!) Como delimitador. El siguiente ejemplo muestra cómo utilizar otros caracteres como delimitadores.

Supongamos que necesita reemplazar la ruta /bin/sed con /home/jerry/src/sed/sed-4.2.2/sed. Por lo tanto, su comando SED se ve así:

[jerry]$ echo "/bin/sed" | sed 's/\/bin\/sed/\/home\/jerry\/src\/sed\/sed-4.2.2\/sed/'

Al ejecutar el código anterior, obtiene el siguiente resultado:

/home/jerry/src/sed/sed-4.2.2/sed

Podemos hacer que este comando sea más legible y fácil de entender. Usemos la barra vertical (|) como delimitador y veamos el resultado.

[jerry]$ echo "/bin/sed" | sed 's|/bin/sed|/home/jerry/src/sed/sed-4.2.2/sed|'

Al ejecutar el código anterior, obtiene el siguiente resultado:

/home/jerry/src/sed/sed-4.2.2/sed

¡En efecto! Obtuvimos el mismo resultado y la sintaxis es más legible. De manera similar, podemos usar el signo "arroba" (@) como delimitador de la siguiente manera:

[jerry]$ echo "/bin/sed" | sed '[email protected]/bin/[email protected]/home/jerry/src/sed/sed-4.2.2/[email protected]'

Al ejecutar el código anterior, obtiene el siguiente resultado:

/home/jerry/src/sed/sed-4.2.2/sed

Además de esto, podemos usar el signo de intercalación (^) como delimitador.

[jerry]$ echo "/bin/sed" | sed 's^/bin/sed^/home/jerry/src/sed/sed-4.2.2/sed^'

Al ejecutar el código anterior, obtiene el siguiente resultado:

/home/jerry/src/sed/sed-4.2.2/sed

También podemos usar el signo de exclamación (!) Como delimitador de la siguiente manera:

[jerry]$ echo "/bin/sed" | sed 's!/bin/sed!/home/jerry/src/sed/sed-4.2.2/sed!'

Al ejecutar el código anterior, obtiene el siguiente resultado:

/home/jerry/src/sed/sed-4.2.2/sed

Generalmente, la barra invertida (/) se usa como delimitador, pero a veces es más conveniente usar otros delimitadores compatibles con SED.

Crear una subcadena

Aprendimos el poderoso comando sustituto. Veamos si podemos encontrar una subcadena de un texto coincidente. Entendamos cómo hacerlo con la ayuda de un ejemplo.

Consideremos el siguiente texto:

[jerry]$ echo "Three One Two"

Supongamos que tenemos que organizarlo en una secuencia. Significa que debería imprimir uno primero, luego dos y finalmente tres. El siguiente one-liner hace lo necesario.

echo "Three One Two" | sed 's|\(\w\+\) \(\w\+\) \(\w\+\)|\2 \3 \1|'

Tenga en cuenta que en el ejemplo anterior, la barra vertical (|) se utiliza como delimitador.

En SED, las subcadenas se pueden especificar utilizando un operador de agrupación y deben tener un prefijo con un carácter de escape, es decir, \( y \).

\wes una expresión regular que coincide con cualquier letra, dígito o guión bajo y "+" se utiliza para coincidir con más de un carácter. En otras palabras, la expresión regular\(\w\+\) coincide con la única palabra de la cadena de entrada.

En la cadena de entrada, hay tres palabras separadas por un espacio, por lo que hay threeexpresiones regulares separadas por espacio. La primera expresión regular almacena la primera palabra, es decir, Tres, la segunda almacena la palabraOney el tercero almacena la palabra Two

Estas subcadenas son referidas por \N,donde N es el número de subcadena. Por lo tanto,\2 imprime la segunda subcadena, es decir, One; \3 imprime la tercera subcadena, es decir, Two; y \1 imprime la primera subcadena, es decir, Three

Separemos estas palabras con comas (,) y modifiquemos la expresión regular en consecuencia.

[jerry]$ echo "Three,One,Two" | sed 's|\(\w\+\),\(\w\+\),\(\w\+\)|\2,\3,\1|'

Al ejecutar el código anterior, obtiene el siguiente resultado:

One,Two,Three

Tenga en cuenta que ahora hay una coma (,) en lugar de un espacio en la expresión regular.

Banderas de reemplazo de cuerdas (solo GNU SED)

En la sección anterior, vimos algunos ejemplos del comando de sustitución. GNU SED proporciona algunas secuencias de escape especiales que pueden usarse en la cadena de reemplazo. Tenga en cuenta que estos indicadores de reemplazo de cadenas son específicos de GNU y es posible que no funcionen con otras variantes de SED. Aquí discutiremos las banderas de reemplazo de cadenas.

  • \ L: cuando se especifica \ L en la cadena de reemplazo, trata todos los caracteres restantes de la palabra después de \ L como caracteres en minúscula. Por ejemplo, los caracteres "ULO" se tratan como caracteres en minúscula.

[jerry]$ sed -n 's/Paulo/PA\LULO/p' books.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

3) The Alchemist, PAulo Coelho, 197
5) The Pilgrimage, PAulo Coelho, 288
  • \ u: Cuando se especifica \ u en la cadena de reemplazo, trata el carácter inmediato después de \ u como un carácter en mayúscula. En el siguiente ejemplo, \ u se usa antes de los caracteres 'a' y 'o'. Por lo tanto, SED trata estos caracteres como letras mayúsculas.

[jerry]$ sed -n 's/Paulo/p\uaul\uo/p' books.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

3) The Alchemist, pAulO Coelho, 197 
5) The Pilgrimage, pAulO Coelho, 288
  • \ U: Cuando se especifica \ U en la cadena de reemplazo, trata todos los caracteres restantes de la palabra después de \ U como caracteres en mayúscula.

[jerry]$ sed -n 's/Paulo/\Upaulo/p' books.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

3) The Alchemist, PAULO Coelho, 197 
5) The Pilgrimage, PAULO Coelho, 288
  • \ E: Esta bandera debe usarse con \ L o \ U. Detiene la conversión iniciada por la bandera \ L o \ U. En el siguiente ejemplo, solo la primera palabra se reemplaza con letras mayúsculas.

[jerry]$ sed -n 's/Paulo Coelho/\Upaulo \Ecoelho/p' books.txt

Al ejecutar el código anterior, obtiene el siguiente resultado:

3) The Alchemist, PAULO coelho, 197 
5) The Pilgrimage, PAULO coelho, 288