stringtranslate.com

sed

sed ("editor de secuencias") es una utilidad de Unix que analiza y transforma texto, utilizando un lenguaje de programación simple y compacto. Fue desarrollado entre 1973 y 1974 por Lee E. McMahon de Bell Labs , [1] y está disponible hoy en día para la mayoría de los sistemas operativos. [2] sed se basó en las características de scripting del editor interactivo ed ("editor", 1971) y el anterior qed ("editor rápido", 1965-66). Fue una de las primeras herramientas en soportar expresiones regulares , y sigue en uso para el procesamiento de texto, más notablemente con el comando de sustitución. Las herramientas alternativas populares para la manipulación de cadenas de texto sin formato y la "edición de secuencias" incluyen AWK y Perl .

Historia

Apareciendo por primera vez en la versión 7 de Unix , [3] sed es uno de los primeros comandos de Unix creados para el procesamiento de archivos de datos desde la línea de comandos. Evolucionó como el sucesor natural del popular comando grep . [4] La motivación original fue un análogo de grep (g/re/p) para la sustitución, de ahí "g/re/s". [3] Previendo que también surgirían otros programas de propósito especial para cada comando, como g/re/d, McMahon escribió un editor de flujo orientado a líneas de propósito general, que se convirtió en sed. [4] La sintaxis de sed, en particular el uso de /para la coincidencia de patrones y s///para la sustitución, se originó con ed , el precursor de sed, que era de uso común en ese momento, [4] y la sintaxis de expresiones regulares ha influido en otros lenguajes, en particular ECMAScript y Perl . Más tarde, se desarrolló el lenguaje más poderoso AWK , y estos funcionaron como primos, lo que permitió que se realizara un procesamiento de texto potente mediante scripts de shell . sed y AWK se citan a menudo como progenitores e inspiración para Perl, e influyeron en la sintaxis y la semántica de Perl, especialmente en los operadores de coincidencia y sustitución.

GNU sed agregó varias características nuevas, incluyendo la edición de archivos en el lugar. Super-sed es una versión extendida de sed que incluye expresiones regulares compatibles con Perl . Otra variante de sed es minised , originalmente diseñada a la inversa a partir de sed 4.1BSD por Eric S. Raymond y actualmente mantenida por René Rebe . minised fue utilizado por el Proyecto GNU hasta que el Proyecto GNU escribió una nueva versión de sed basada en la nueva biblioteca de expresiones regulares de GNU. El minised actual contiene algunas extensiones de sed BSD pero no es tan rico en características como sed GNU. Su ventaja es que es muy rápido y utiliza poca memoria. Se utiliza en sistemas embebidos y es la versión de sed proporcionada con Minix . [5]

Modo de funcionamiento

sed es una utilidad de procesamiento de texto orientada a líneas: lee texto, línea por línea, desde un flujo de entrada o archivo, en un búfer interno llamado espacio de patrones . Cada línea leída inicia un ciclo . Al espacio de patrones, sed aplica una o más operaciones que se han especificado mediante un script sed . sed implementa un lenguaje de programación con aproximadamente 25 comandos que especifican las operaciones sobre el texto. Para cada línea de entrada, después de ejecutar el script, sed normalmente genera el espacio de patrones (la línea modificada por el script) y comienza el ciclo nuevamente con la línea siguiente. Otros comportamientos de fin de script están disponibles a través de las opciones de sed y los comandos de script, por ejemplo, deliminar el espacio de patrones, qsalir, Nagregar la siguiente línea al espacio de patrones inmediatamente, etc. Por lo tanto, un script sed corresponde al cuerpo de un bucle que itera a través de las líneas de un flujo, donde el bucle en sí y la variable de bucle (el número de línea actual) son implícitos y mantenidos por sed.

El script sed puede especificarse en la línea de comandos ( -eopción) o leerse desde un archivo separado ( -fopción). Los comandos en el script sed pueden tomar una dirección opcional, en términos de números de línea o expresiones regulares . La dirección determina cuándo se ejecuta el comando. Por ejemplo, 2dsolo ejecutaría el dcomando (delete) en la segunda línea de entrada (imprimiendo todas las líneas excepto la segunda), mientras que /^ /deliminaría todas las líneas que comiencen con un espacio. Un búfer especial separado, el espacio de retención , puede ser utilizado por algunos comandos sed para retener y acumular texto entre ciclos. El lenguaje de comandos de sed tiene solo dos variables (el "espacio de retención" y el "espacio de patrones") y una funcionalidad de ramificación similar a GOTO ; sin embargo, el lenguaje es Turing-completo , [6] [7] y existen scripts sed esotéricos para juegos como sokoban , arkanoid , [8] ajedrez , [9] y tetris . [10]

Un bucle principal se ejecuta para cada línea del flujo de entrada, evaluando el script sed en cada línea de la entrada. Cada línea de un script sed es un par patrón-acción, que indica qué patrón hacer coincidir y qué acción realizar, lo que puede reformularse como una declaración condicional . Debido a que el bucle principal, las variables de trabajo (espacio de patrones y espacio de retención), los flujos de entrada y salida y las acciones predeterminadas (copiar línea al espacio de patrones, imprimir espacio de patrones) son implícitos, es posible escribir programas concisos de una sola línea . Por ejemplo, el programa sed dado por:

10q

imprimirá las primeras 10 líneas de entrada y luego se detendrá.

Uso

Comando de sustitución

El siguiente ejemplo muestra un uso típico y más común de sed: la sustitución. Este uso fue, de hecho, la motivación original de sed: [4]

sed 's/regexp/replacement/g' nombreArchivoEntrada > nombreArchivoSalida    

En algunas versiones de sed, la expresión debe ir precedida de -epara indicar que sigue una expresión. El ssignifica sustituto, mientras que el gsignifica global, lo que significa que se reemplazarán todas las ocurrencias coincidentes en la línea. La expresión regular (es decir, patrón) que se buscará se coloca después del primer símbolo delimitador (barra oblicua aquí) y el reemplazo sigue al segundo símbolo. La barra oblicua ( /) es el símbolo convencional, que se origina en el carácter para "buscar" en ed, pero se puede usar cualquier otro para hacer que la sintaxis sea más legible si no aparece en el patrón o reemplazo; esto es útil para evitar el " síndrome del palillo inclinado ".

El comando de sustitución, que se origina en la función de búsqueda y reemplazo en ed, implementa un análisis y una creación de plantillas simples . regexpProporciona coincidencia de patrones y guarda texto mediante subexpresiones, mientras que replacementpuede ser texto literal o una cadena de formato que contenga los caracteres &para "coincidencia completa" o las secuencias de escape \1 especiales hasta \9para la n.ª subexpresión guardada. Por ejemplo, sed -r "s/(cat|dog)s?/\1s/g"reemplaza todas las ocurrencias de "gato" o "perro" con "gatos" o "perros", sin duplicar una "s" existente: (cat|dog)es la primera (y única) subexpresión guardada en la expresión regular y, \1en la cadena de formato, la sustituye en la salida.

Otros comandos sed

Además de la sustitución, existen otras formas de procesamiento simple que se pueden realizar mediante el uso de unos 25 comandos sed. Por ejemplo, el siguiente comando utiliza el comando d para filtrar líneas que solo contienen espacios o que solo contienen el carácter de fin de línea:

sed '/^ *$/d' nombreArchivoEntrada  

Este ejemplo utiliza algunos de los siguientes metacaracteres de expresiones regulares (sed admite la gama completa de expresiones regulares):

Son posibles construcciones sed complejas, lo que le permite servir como un lenguaje de programación simple, pero altamente especializado . El flujo de control, por ejemplo, se puede gestionar mediante el uso de una etiqueta (dos puntos seguidos de una cadena) y la instrucción de bifurcación b, así como la bifurcación condicional t. Una instrucción bseguida de un nombre de etiqueta válido moverá el procesamiento al comando que sigue a esa etiqueta. La tinstrucción solo lo hará si hubo una sustitución exitosa desde la anterior t(o el inicio del programa, en caso de la primera tencontrada). Además, la {instrucción inicia una subsecuencia de comandos (hasta el }); en la mayoría de los casos, estará condicionada por un patrón de dirección.

sed utilizado como filtro

En Unix, sed se utiliza a menudo como filtro en una canalización :

$ generarDatos | sed 's/x/y/g'   

Es decir, un programa como "generateData" genera datos y luego sed realiza el pequeño cambio de reemplazar x por y . Por ejemplo:

$ echo  xyz  xyz | sed 's/x/y/g' yyz yyz   

[notas 1]

Scripts sed basados ​​en archivos

A menudo resulta útil colocar varios comandos sed, un comando por línea, en un archivo de script como subst.sed, y luego usar la -fopción para ejecutar los comandos (como s/x/y/g) desde el archivo:

sed  -f  subst.sed  nombreArchivoEntrada  >  nombreArchivoSalida

Se puede colocar cualquier cantidad de comandos en el archivo de script, y el uso de un archivo de script también evita problemas con el escape o las sustituciones del shell.

Un archivo de script de este tipo se puede ejecutar directamente desde la línea de comandos si se le antepone una " línea shebangsubst.sed " que contenga el comando sed y se le asigna el permiso de ejecución. Por ejemplo, se puede crear un archivo con el contenido siguiente:

#!/bin/sed -fs / x / y / g

El usuario actual podrá luego hacer que el archivo sea ejecutable con el chmodcomando:

chmod  u+x  subst.sed

El archivo puede luego ejecutarse directamente desde la línea de comando:

subst.sed  nombreArchivoEntrada  >  nombreArchivoSalida

Edición en el lugar

La -iopción, introducida en GNU sed, permite la edición de archivos en el lugar (en realidad, se crea un archivo de salida temporal en segundo plano y luego el archivo original se reemplaza por el archivo temporal). Por ejemplo:

sed  -i 's/abc/def/' nombreArchivo  

Ejemplos

Hola mundo! ejemplo

# convierte el flujo de texto de entrada a "¡Hola, mundo!" s / .* / ¡Hola, mundo! / q

Este script "¡Hola, mundo!"sed -f script.txt inputFileName está en un archivo (por ejemplo, script.txt) y se invoca con , donde "inputFileName" es el archivo de texto de entrada. El script cambia la línea n.° 1 de "inputFileName" por "¡Hola, mundo!" y luego se cierra, imprimiendo el resultado antes de que sed salga. Las líneas de entrada posteriores a la línea n.° 1 no se leen ni se imprimen. Por lo tanto, la única salida es "¡Hola, mundo!".

El ejemplo resalta muchas características clave de sed:

Otros ejemplos sencillos

A continuación se muestran varios scripts sed; estos pueden ejecutarse pasándolos como argumento a sed, o colocándolos en un archivo separado y ejecutándose a través de -fo haciendo que el script en sí sea ejecutable.

Para reemplazar cualquier instancia de una determinada palabra en un archivo con "REDACTADO", como una contraseña de IRC, y guardar el resultado:

$ sed  -i "s/tucontraseña/REDACTADA/" ./status.chat.log  

Para eliminar cualquier línea que contenga la palabra "tupalabra" (la dirección es '/tupalabra/'):

/ tupalabra / d 

Para eliminar todas las instancias de la palabra "tupalabra":

s / tupalabra // g

Para eliminar dos palabras de un archivo simultáneamente:

s / primera palabra // g s / segunda palabra // g

Para expresar el ejemplo anterior en una línea, como al ingresar en la línea de comando, se pueden unir dos comandos mediante el punto y coma:

$ sed "s/primerapalabra//g; s/segundapalabra//g" nombreArchivoEntrada  

Ejemplo de procesamiento multilínea

En el siguiente ejemplo, sed, que normalmente solo funciona en una línea, elimina los saltos de línea de las oraciones en las que la segunda línea comienza con un espacio. Considere el siguiente texto:

Este es mi perro, cuyo nombre es Frank.Este es mi pez,cuyo nombre es George.Esta es mi cabra, cuyo nombre es Adán.

El script sed que aparece a continuación convertirá el texto anterior en el siguiente. Tenga en cuenta que el script afecta únicamente a las líneas de entrada que comienzan con un espacio:

Este es mi perro, cuyo nombre es Frank.Este es mi pez,cuyo nombre es George.Esta es mi cabra, cuyo nombre es Adán.

El guión es:

 N s / \n / / P D    

Esto se explica así:

Esto se puede expresar en una sola línea mediante punto y coma:

sed ' ' nombreArchivoEntradaN; s/\n / /; P; D

Limitaciones y alternativas

Aunque es simple y limitado, sed es lo suficientemente potente para una gran cantidad de propósitos. Para un procesamiento más sofisticado, se utilizan lenguajes más potentes como AWK o Perl . Estos se utilizan particularmente si se transforma una línea de una manera más complicada que una extracción de expresiones regulares y un reemplazo de plantilla, aunque en principio es posible realizar transformaciones arbitrariamente complicadas utilizando el búfer de retención.

Por el contrario, para operaciones más sencillas, suelen ser preferibles utilidades especializadas de Unix como grep (imprime líneas que coinciden con un patrón), head (imprime la primera parte de un archivo), tail (imprime la última parte de un archivo) y tr (traduce o elimina caracteres). Para las tareas específicas para las que están diseñadas, estas utilidades especializadas suelen ser más sencillas, claras y rápidas que una solución más general como sed.

Los comandos y la sintaxis de ed/sed siguen utilizándose en programas descendientes, como los editores de texto vi y vim . Un análogo de ed/sed es sam /ssam, donde sam es el editor de Plan 9 y ssam es una interfaz de flujo para él, que ofrece una funcionalidad similar a sed.

Véase también

Notas

  1. ^ En el uso de la línea de comandos, las comillas alrededor de la expresión no son obligatorias y solo son necesarias si el shell no interpretaría la expresión como una sola palabra (token). Para el script s/x/y/gno hay ambigüedad, por lo que generateData | sed s/x/y/gfunciona correctamente. Sin embargo, las comillas se incluyen generalmente para mayor claridad y a menudo son necesarias, especialmente para espacios en blanco (por ejemplo, 's/x x/y y/'). La mayoría de las veces se utilizan comillas simples para evitar que el shell interprete $como una variable del shell. Se utilizan comillas dobles, como "s/$1/$2/g", para permitir que el shell sustituya un argumento de la línea de comandos u otra variable del shell.

Referencias

  1. ^ "Preguntas frecuentes sobre sed, sección 2.1". Archivado desde el original el 27 de junio de 2018. Consultado el 21 de mayo de 2013 .
  2. ^ "Preguntas frecuentes sobre sed, sección 2.2". Archivado desde el original el 27 de junio de 2018. Consultado el 21 de mayo de 2013 .
  3. ^ ab McIlroy, MD (1987). Un lector de Unix para investigación: extractos anotados del Manual del programador, 1971–1986 (PDF) (Informe técnico). CSTR. Bell Labs. 139.
  4. ^ abcd "Sobre la historia temprana y el impacto de Unix". Un tiempo después surgió la demanda de otro programa de propósito especial, gres, para la sustitución: g/re/s. Lee McMahon se encargó de escribirlo y pronto previó que la familia no tendría fin: g/re/d, g/re/a, etc. A medida que su concepto se fue desarrollando, se convirtió en algo habitual…
  5. ^ Raymond, Eric Steven ; Rebe, René (3 de marzo de 2017). «tar-mirror/minised: una implementación de SED más pequeña, más barata y más rápida». GitHub . Archivado desde el original el 13 de junio de 2018 . Consultado el 20 de mayo de 2024 .
  6. ^ "Implementación de una máquina de Turing como secuencia de comandos Sed". Archivado desde el original el 20 de febrero de 2018. Consultado el 24 de abril de 2003 .
  7. ^ "Turing.sed". Archivado desde el original el 16 de enero de 2018. Consultado el 24 de abril de 2003 .
  8. ^ "El hogar de $SED - gamez".
  9. ^ "bolknote/SedChess". GitHub . Consultado el 23 de agosto de 2013 .
  10. ^ "Sedtris, un juego de Tetris escrito para sed". GitHub . Consultado el 3 de octubre de 2016 .

Lectura adicional

Enlaces externos