Reemplazar cadena con contenido de un archivo usando sed


23

Tengo dos archivos diferentes:

Archivo1

/home/user1/  
/home/user2/bin  
/home/user1/a/b/c

File2

<TEXT1>
<TEXT2>

Quiero reemplazar el <TEXT1>de File2 con el contenido de File1 usando sed. Intenté este comando, pero no obtuve el resultado adecuado:

cat File2|sed "s/<TEXT1>/$(cat File1|sed 's/\//\\\//g'|sed 's/$/\\n/g'|tr -d "\n")/g"

Puede usar otras herramientas también para resolver este problema.


Pegue ese mensaje de error para que podamos localizar su fuente. También díganos qué sedimplementación está utilizando. Tu código funciona para mí con GNU sed.
manatwork

Lo sentimos, no obtengo un error. No estoy obteniendo la salida deseada. La salida es como /home/user1/ n/home/user2/bin n/home/user1/a/b/cn <TEXT2>. No obteniendo nuevas líneas.
chanchal1987

No estoy seguro de si esto se aplicaría en su caso específico, pero con diffy las patchherramientas permiten reemplazar algunas líneas en un archivo por otras líneas con bastante facilidad.
Stéphane Gimenez

1
Por cierto, el uso de datos aleatorios recopilados $()en un script sed hace que mis ojos sangren. Nunca use datos externos en lugares donde algunos caracteres se interpretan con un significado especial.
Stéphane Gimenez

Respuestas:


24

Aquí hay una solución de script sed (más fácil a la vista que tratar de ponerla en una línea en la línea de comando):

/<TEXT1>/ {
  r File1
  d
}

Ejecutándolo:

$ sed -f script.sed File2
/home/user1/
/home/user2/bin
/home/user1/a/b/c
<TEXT2>

Gracias, esto está funcionando. Pero no quiero usar ningún otro archivo de script. ¿Hay alguna solución en línea?
chanchal1987

Claro: sed '/<TEXT1>/{rFile1^Md^M}' File2donde "^ M" presionas volver. El problema es que sed realmente necesita las nuevas líneas dentro de {...} para delimitar los comandos r y d.
Kusalananda

66
con bash, las cuerdas de estilo posix son un poco más limpias:sed $'/<TEXT1>/ {r File1\n d}'
glenn jackman

99
También con -e para un trazador de líneas:sed -e '/<TEXT1>/{r File1' -e 'd}' File2
sdaau

1
¿Y si en lugar de reemplazar toda la línea que contiene <TEXT1>, solo quiero reemplazar la cadena en sí, dejando el resto de la línea intacta? Text1: <TEXT1>a Text1: <file_contents>.
Robin Winslow

9

Me tomó mucho tiempo encontrar esta solución usando el reemplazo de var. Todas las soluciones sed no funcionaron para mí, ya que eliminan líneas completas o las reemplazan incorrectamente.

FILE2=$(<file2)
FILE1=$(<file1)
echo "${FILE2//TEXT1/$FILE1}" 

Reemplaza todas las ocurrencias de TEXT1 en el archivo2 contra el contenido del archivo1. El resto del texto permanece intacto.


muy agradable. posiblemente más rápido que sedtambién, ya que esas "expansiones" (también conocidas como reemplazos) están integradas en el caparazón ( bashal menos)
amarillo

7

Respondo porque el método diff/ patchpuede ser de interés en algunos casos. Para definir una sustitución de líneas contenidas en el archivo blob1por líneas contenidas en blob2uso:

diff -u blob1 blob2 > patch-file

Por ejemplo, si blob1contiene:

hello
you

y blob2contiene:

be
welcome
here

el generado patch-fileserá:

--- blob1   2011-09-08 16:42:24.000000000 +0200
+++ blob2   2011-09-08 16:50:48.000000000 +0200
@@ -1,2 +1,3 @@
-hello
-you
+be
+welcome
+here

Ahora, puede aplicar este parche a cualquier otro archivo:

patch somefile patch-file

Se reemplazará hello, youlíneas de be, welcome, herelíneas en somefile.


esto es realmente inteligente, pero sería mejor si pudiera automatizar en un script
qodeninja
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.