Articles

Ejemplos de Bash Sed

Bash permite realizar el reemplazo de patrones mediante la expansión de variables como (${var/patrón/reemplazo}). Y también lo hace sed así (sed -e ‘s/patrón/reemplazo/’). Sin embargo, hay más en sed que el reemplazo de patrones en archivos de texto. Aquí vamos a redescubrir sed, con ejemplos, con comandos equivalentes y flujos de trabajo para ayudar en las tareas del día a día.

Configuración para los ejemplos de sed

Aquí tienes una guía rápida para configurarte para el ejemplo, que intentaré que no sea demasiado exagerado.

«palabras» es un archivo de texto que contiene los números del 1 al 100. Si no estás seguro del comando para crearlo, consulta la función Exportar para xargs en Bash Export Command. Nunca se sabe que puede estar en su próxima entrevista de shell scripting.

«bar» es un archivo de texto que contiene una sola línea -.

«old-php» es un archivo de texto que contiene líneas de PHP antiguo que se romperá en php7 o posterior. (Sugerencia: ereg)

Nota que todas las funciones descritas anteriormente se pueden encontrar más abajo en la nota final sobre las funciones para la configuración.

Ejemplos con comandos equivalentes

En un entorno de línea de comandos, encontrará que hay más de una solución para una tarea determinada. Sin embargo, en la mayor parte de los casos, usted querrá ir con el camino que produzca la menor resistencia. Aquí hay una lista de ejemplos de comandos sed con sus correspondientes comandos equivalentes, donde algunos serán cubiertos en detalle a continuación.

1. Imprimir una línea aleatoria (equivalente a sort -R – | head -1)

sed -n «$(( RANDOM % 100 ))p» –

2.Imprimir la última línea de un fichero (equivalente a head -1 -)

sed -n ‘$p’ –

3. Imprimir las 10 primeras líneas de un fichero (equivalente a head -n 10 -)

sed ’10q’ –

4. Imprimir la primera línea de un archivo (equivalente a tail -1 -)

sed -n ‘1p’ –

5. Borrar todas las instancias de un carácter (equivalente a tr -delete ‘0’ -, donde 0 es el carácter que queremos borrar)

sed -e ‘s/0//g’ –

6. Convertir el archivo csv en tsv (equivalente a tr ‘,’ ‘\t’ -)

sed -e ‘s/,/\t/g’ –

7.Anexar línea al archivo (equivalente a cat bar -)

sed ‘$a —‘ –

8. Anexar línea al archivo (equivalente a cat – bar)

sed ‘1i —‘ –

9. Imprimir todas las líneas del archivo (equivalente a cat -)

sed -n -e ‘p’ –

10. Imprimir las líneas que coincidan con un patrón (equivalente a grep -e ‘^1’ -)

sed -n -e ‘/^1/ p’ –

11. Eliminar las líneas que coinciden con un patrón (equivalente a grep -v -e ‘^1’ -)

sed -e ‘/^1/ d’ –

12. Obtener el número de líneas de un fichero (equivalente a wc -l -)

sed -n -e ‘$=’ –

13. Escribir en un archivo en segundo plano(comando equivalente tee)

sed «w ${1}» –

Ejemplo de uso de sed para implementar el comando tee

Justo arriba, hay un ejemplo etiquetado como Escribir en un archivo en segundo plano. Suena un poco como el comando tee. Pues bien, lo es. Aquí ampliaremos cómo implementar una función que sustituya a tee en bash utilizando sed.

Comandos

tee ()
{
probar ${#} -eq 1 || return;
sed «w ${1}» –
}
main ()
{
seq 10 | tee ten;
cat diez
}
main

Salida

1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10

Aquí verás dos listados de los enteros del 1 al 10. El primero es del comando seq. El segundo lo obtenemos del cat del fichero escrito en tee. Sé que es ridículo pero funciona¡

Ejemplo de uso de sed para imprimir una línea aleatoria en un fichero

Supongamos que queremos imprimir una línea aleatoria en un fichero usando bash y un poco de sed. ¿Podemos hacerlo? Sí, ¡podemos! He aquí cómo.

Implementa una función que

  1. Obtiene el número de líneas de un fichero, L
  2. Genera un número aleatorio entre 1 y L, R
  3. Imprime R

La función espera que la entrada sea canalizada desde el exterior.

Comandos

some-line ()
{
función lc ()
{
sed -n -e ‘$=’ –
};
función print-line ()
{
sed -n -e «${1}p» –
};
temp=$( mktemp );
cat – > ${temp};
cat ${temp} | print-line $(( RANDOM % $( cat ${temp} | lc ) + 1 ));
rm ${temp}
}

Ejemplo de uso (1)

seq 100 | _

Salida (1)

35

Ejemplo de uso (2)

curl https://linuxhint.com/bash_cut_command/ –silent | strip-tags | some-line

Vea el ejemplo siguiente, utilizando sed para eliminar las etiquetas HTML. Observe que el ejemplo de sed a veces devuelve en blanco las líneas vacías. Como ejercicio, se puede mejorar.

Usando sed para imprimir líneas en un archivo

Suponga que quiere implementar una función en bash para imprimir una línea determinada en un archivo. Tratar de imprimir una sola línea en un archivo usando un bucle en bash, head, tail o awk es demasiado trabajo para imprimir líneas en un archivo. Menos mal que tenemos sed. La función resultante usando sed sería la siguiente.

Comandos

imprimir-línea ()
{br>sed -n «${1}p» –
}

Ahora vamos a ver qué pasa cuando usamos print-line en las palabras.

Comandos

palabras | print-line 50

Salida

50

Bien. Se ve bien pero probemos algo que parece un poco menos trivial.

Comandos

declarar -xf palabras
declarar -xf línea de impresión
seq 1 10 $( palabras | wc -l ) | xargs -i bash -c «palabras | línea de impresión {}»

Salida

1
11
21
31
41
51
61
71
81
91

Bien. ¡Eso sí que es más bien un poco de lo mismo! Ya ves cómo se puede utilizar sed en un script de bash para imprimir cualquier línea de un archivo.

Ejemplos de sed sin comandos equivalentes

En un entorno de línea de comandos, a veces el camino a una solución que rinde la menor resistencia es el camino de sed; de lo contrario, acabas haciendo más trabajo del necesario en primer lugar. Algunos comandos pueden aparecer a continuación.

Comandar todas las líneas de un script de shell

sed -e ‘s/^/#/’ –
Borrar la primera línea
sed -e ‘1d’ –
Borrar la última línea
sed -e ‘$ d’ –
Insertar una línea antes de las líneas que coinciden con un patrón
sed ‘/0$/i —‘ –
Insertar una línea después de las líneas que coinciden con un patrón
sed ‘/0$/ —‘ –
Quitar las etiquetas html
sed -e ‘s/<*.//g’ –
Actualizar ereg en código php antiguo para que funcione en php7 o posterior
sed ‘s/ereg(\(*\).\(*\)./strpos(\2,\1)/g’
Comprobar si sed es anterior a una determinada versión
sed -e ‘v 4.5’ –

Ejemplo de bifurcación de versiones de sed en bash

Sobre los ejemplos, hay una línea para Comprobar si sed es anterior a una determinada versión que podemos utilizar para implementar la bifurcación de versiones en bash, que creo que es más fácil que tratar de implementar una función para comparar los números de versión desde la salida de sed -versión. Ese único escollo es que si hay una versión anterior de sed que no soporta el comando v, entonces estamos en problemas.

Comandos

test-sed-version-at-most() {
echo -n | sed «v ${1}» – 2>/dev/null
}
probar-versión ()
{
echo -n «Versión ${1}. Bien. Hágalo el «;
probar-versión-máxima ${1} && {
echo -n «antigua»;
true
} || {
echo -n «nuevo»
};
echo » camino.»
}
main ()
{
local v;
for v in 4.{4,5};
hacer
intentar-versión ${v};
hecho
}
main

Salida

Versión 4.4. Bien. Hazlo de la manera antigua.
Versión 4.5. Bien. Hazlo de la nueva manera.

Nótese que la versión de sed que se ejecuta en mi máquina en el momento de escribir estos caracteres es la 4.4, lo que explicaría la salida anterior. Además, al mismo tiempo, la última versión de gnu sed era la 4.7, unos 3 años más antigua que la que tengo. ¡Mi sed es viejo! De hecho, en sed 4.0.6, se añadió un parámetro al comando de la versión, por lo que esta estrategia funciona para cualquier dijo al menos v4.0.6, lo cual es indulgente teniendo en cuenta que esa versión fue lanzada a principios de 2003. Eres bueno.

Hice un poco de investigación adicional, en realidad NOTICIAS lectura del último código fuente. La versión 4.6 tiene una nueva característica, -debug que vuelca el script y anota las líneas de salida. Esto permitiría traducir a forma canónica los scripts sed generados por funciones en bash. ¡Genial! Sólo no olvides que necesitas la ramificación de la versión de sed en bash. Ahí es donde entra en juego este ejemplo de sed.

Ejemplo de función bash usando sed para despojar las etiquetas HTML

En los ejemplos anteriores hay una línea para Despojar las etiquetas HTML. Vamos a lanzar eso en una función bash y usarla para despojar todas las etiquetas HTML del último artículo que escribí.

Comandos

despojar etiquetas ()
{
sed -e ‘s/<*.//g’ –
}
curl https://linuxhint.com/bash_cut_command/ –silent | strip-tags

No puedo decir que sea perfecto pero al menos es legible en la terminal.

Ejemplos con flujos de trabajo: Ejemplo de flujo de trabajo: reemplazar todo de forma segura usando find, grep y sed

Es seguro decir que los cambios hechos usando sed con la opción -i son irreversibles. Es decir, a menos que esté completamente seguro de qué texto se va a reemplazar, es probable que termine con un carácter menos de lo previsto. Es por ello que en este ejemplo, utilizaremos sed en un flujo de trabajo para reemplazar de forma segura el texto en todos los archivos que hayas seleccionado.

Flujo de trabajo

  1. encontrar
  2. grep
  3. sed
encontrar

Aquí seleccionarás los archivos que serán objeto de reemplazo. Te sugiero que utilices un comando del estilo:

find -type f -name | grep -v -e | xargs -i …

Por ejemplo, puedes querer limitar los archivos a reemplazar a los archivos PHP excluyendo los directorios del repositorio git de la siguiente manera.

find -type f -name \*.php | grep -v -e ‘.git’ | xargs -i …

Lee más sobre el comando xargs en bash.

grep

A continuación, vamos a intentar hacer coincidir algún_patrón en los archivos seleccionados de la siguiente manera. Ten en cuenta que como estamos usando la opción -o para grep, la salida sólo mostrará la cadena coincidente si la hay.

find -type f -name \*.php | grep -v -e ‘.git’ |
xargs -i grep -e some_pattern -o

El comando anterior debería devolver una lista de cadenas que coincidan con some_pattern.

sed

Por último, queremos reemplazar todas las cadenas que coincidan con some_pattern. Para ello tenemos que convertir grep en sed de la siguiente manera.

find -type f -name \*.php | grep -v -e ‘.git’ |
xargs -i sed -i -e s/some_pattern/replacement/g

El comando grep se convierte en sed -i y se elimina la opción -o. Y ahí lo tienes.

Ahora puedes comprobar qué cadenas van a ser reemplazadas en sed de antemano en lugar de probar tu suerte.

Notas finales sobre las opciones utilizadas en los ejemplos

Aquí tienes una lista de opciones utilizadas en los ejemplos de sed comentados brevemente.

Descripción
-i Edición en el lugar. Si la entrada es un fichero (no canalizado) el resultado de las expresiones sobrescribirá el contenido del fichero.

Sed acepta una

eg) sed -n …

-e -e significa expresión. Su parámetro es una expresión en el lenguaje sed.

Sed acepta muchas

eg) sed -e ‘expr1′ -e ‘expr2’ …

-n Oculta la línea no afectada por la expresión. Es decir, si la expresión es una declaración de impresión en el lenguaje sed, entonces las líneas no incluidas en la declaración de impresión no se incluirán en la salida.

eg) sed -n …

Para más información sobre las opciones de sed disponibles, consulte sed -help

Notas finales sobre el uso de comandos equivalentes en los ejemplos

Las siguientes utilidades de línea de comandos se incluyen en los ejemplos de sed con comandos equivalentes.

  • sort
  • head
  • tail
  • grep
  • cat
  • Tr
  • tee
    • Nota final sobre el carácter – al final de los comandos equivalentes de los ejemplos

      En caso de que te preguntes qué pasa con el carácter – en el ejemplo, esta nota es para ti. He añadido un carácter – después de la mayoría de los comandos en los ejemplos para dar a entender que esperamos que la entrada se reciba a través de una tubería. Es decir,

      cat some-file | sort -R – | head -1

      Sin embargo, cuando el comando de la izquierda la tubería está presente, podemos omitir la pista de la siguiente manera.

      cat some-file | sort -R | head -1

      Eso es lo que ocurría con el carácter – después de los comandos en los ejemplos.

      Notas finales de las funciones para la configuración

      En caso de que estés buscando, aquí están las funciones para la configuración de los ejemplos anteriores. La salida obtenida usando declare -f. Lee más sobre el comando declare en bash para más usos.

      Comandos

      palabras ()
      {
      seq 100
      }
      bar ()
      {
      echo —
      }
      old-php ()
      {
      echo ‘ereg($UA, «Bottybot»)’
      }

      Línea de fondo

      Disfruté escribiendo los ejemplos de Bash sed e incluso aprendí algunos trucos extra en el camino. Sed es una poderosa utilidad de línea de comandos y un lenguaje expresivo para manipular archivos de texto. Si te ha gustado aprender sobre sed, no te preocupes que aún queda mucho por tocar. Sed on.

Dejar una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *