Reemplazar toda la línea que contiene una cuerda usando Sed

Tengo un archivo de texto que tiene una línea en particular algo así como

sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext 

Necesito reemplazar toda la línea de arriba con

 This line is removed by the admin. 

La palabra clave de búsqueda es TEXT_TO_BE_REPLACED

Necesito escribir un script de shell para esto. ¿Cómo puedo lograr esto usando sed ?

Puede usar el comando de cambio para reemplazar la línea completa, y el indicador -i para realizar los cambios en el lugar. Por ejemplo, usando GNU sed:

 sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo 

Debe usar wildards ( .* ) Antes y después para reemplazar toda la línea:

 sed 's/.*TEXT_TO_BE_REPLACED.*/This line is removed by the admin./' 

La respuesta aceptada no funcionó para mí por varias razones:

  • mi versión de sed no le gusta -i con una extensión de longitud cero
  • la syntax del comando c\ es extraña y no pude hacer que funcione
  • No me di cuenta de que algunos de mis problemas provienen de barras no cortadas

Así que aquí está la solución que se me ocurrió que creo que debería funcionar para la mayoría de los casos:

 function escape_slashes { sed 's/\//\\\//g' } function change_line { local OLD_LINE_PATTERN=$1; shift local NEW_LINE=$1; shift local FILE=$1 local NEW=$(echo "${NEW_LINE}" | escape_slashes) sed -i .bak '/'"${OLD_LINE_PATTERN}"'/s/.*/'"${NEW}"'/' "${FILE}" mv "${FILE}.bak" /tmp/ } 

Entonces, el uso de la muestra para solucionar el problema planteado:

 change_line "TEXT_TO_BE_REPLACED" "This line is removed by the admin." yourFile 

La respuesta anterior:

 sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo 

Funciona bien si la cadena / línea de reemplazo no es una variable.

El problema es que en Redhat 5 el \ después de que c escapa del $ . Un doble \\ tampoco funcionó (al menos en Redhat 5).

A través del golpe y la prueba, descubrí que el \ after the c es redundante si su string / line de reemplazo es solo una línea. Así que no usé \ después de la c , usé una variable como una sola línea de reemplazo y fue alegría.

El código sería algo así como:

 sed -i "/TEXT_TO_BE_REPLACED/c $REPLACEMENT_TEXT_STRING" /tmp/foo 

Tenga en cuenta el uso de comillas dobles en lugar de comillas simples.

En mi archivo MAKE uso esto:

 @sed -i '/.*Revision:.*/c\'"`svn info -R main.cpp | awk '/^Rev/'`"'' README.md 

PD: NO olvide que el -i cambia realmente el texto en el archivo … por lo que si el patrón que definió como “Revisión” cambiará, también cambiará el patrón para reemplazarlo.

Ejemplo de salida:

Abc-Project escrito por John Doe

Revisión: 1190

Entonces, si configura el patrón “Revisión: 1190”, obviamente no es lo mismo que los definió como “Revisión”: solo …

 bash-4.1$ new_db_host="DB_HOSTNAME=good replaced with 122.334.567.90" bash-4.1$ bash-4.1$ sed -i "/DB_HOST/c $new_db_host" test4sed vim test4sed ' ' ' DB_HOSTNAME=good replaced with 122.334.567.90 ' 

funciona bien

Todas las respuestas proporcionadas hasta el momento suponen que usted sabe algo sobre el texto a reemplazar que tiene sentido, ya que eso es lo que pidió el OP. Proporciono una respuesta que supone que no sabe nada sobre el texto que se va a reemplazar y que puede haber una línea separada en el archivo con el mismo contenido o contenido similar que no desea que se reemplace. Además, supongo que sabes el número de línea de la línea que se reemplazará.

Los siguientes ejemplos demuestran la eliminación o cambio de texto por números de línea específicos:

 # replace line 17 with some replacement text and make changes in file (-i switch) # the "-i" switch indicates that we want to change the file. Leave it out if you'd # just like to see the potential changes output to the terminal window. # "17s" indicates that we're searching line 17 # ".*" indicates that we want to change the text of the entire line # "REPLACEMENT-TEXT" is the new text to put on that line # "PATH-TO-FILE" tells us what file to operate on sed -i '17s/.*/REPLACEMENT-TEXT/' PATH-TO-FILE # replace specific text on line 3 sed -i '3s/TEXT-TO-REPLACE/REPLACEMENT-TEXT/' 
 cat find_replace | while read pattern replacement ; do sed -i "/${pattern}/c ${replacement}" file done 

El archivo find_replace contiene 2 columnas, c1 con el patrón para que coincida, c2 con reemplazo, el bucle sed reemplaza cada línea que concuerda con uno de los patrones de la variable 1

Es similar al anterior.

 sed 's/[A-Za-z0-9]*TEXT_TO_BE_REPLACED.[A-Za-z0-9]*/This line is removed by the admin./' 

Muy a menudo uso la expresión regular para extraer datos de los archivos que acabo de utilizar para reemplazar la cita literal \" con // nada 🙂

 cat file.csv | egrep '^\"([0-9]{1,3}\.[0-9]{1,3}\.)' | sed s/\"//g | cut -d, -f1 > list.txt