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:
-i
con una extensión de longitud cero c\
es extraña y no pude hacer que funcione 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