Tengo un archivo que tiene (muchas) cadenas que me gustaría reemplazar, así que pensé en usar un comando simple como:
sed 's/string1/string2/g' file1 > out
Sin embargo, hay demasiadas cadenas para repetirlas manualmente. Así que hice una lista de todas las cadenas que se reemplazarían, cada una en una línea, y la nombré archivo A. Luego hice una lista de todas las cadenas de reemplazo y la nombré archivo B.
¿Hay alguna manera de hacer algo como:
sed 's/line i of file A/line i of file B/g' file1 > out
para cada línea del archivo A?
Respuesta1
Sería más fácil crear un archivo con las cadenas de entrada y de reemplazo en la misma línea (suponiendo que ni las cadenas de entrada ni las de reemplazo contengan espacios). Entonces puedes hacerlo algo simple como:
while read n k; do sed -i "s/$n/$k/g" file1; done < fileA
EDITAR:
Después de ver la respuesta de Nykakin, me di cuenta de que puedes hacer lo mismo con los dos archivos que tienes combinando su sugerencia con la mía:
paste fileA fileB | while read n k; do sed -i "s/$n/$k/g" file1; done
Respuesta2
Esta es básicamente su primera idea, pero con los comandos de sustitución colocados en un archivo, son más manejables:
tmpfile=/tmp/Asasuser.$$ ejecutivo 3< archivoA ejecutivo 4< archivoB mientras se lee –r una cadena <&3 hacer leer –r cadena b <&4 echo "s/$astring/$bstring/" >> "$tmpfile" hecho ejecutivo 3<&- 4<&- sed –f "$tmpfile" archivo1 > salida rm –f "$archivotmp"
Esto supone que fileA
y fileB
tienen el mismo número de líneas (y que ese número es mayor que cero) y que ninguno de ellos tiene /
caracteres sin escape.
Respuesta3
Podemos simplemente generar el comando que necesitamos. Digamos que los archivos con listas se llaman lista y listb. Entonces podemos usar:
$ for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done
para generar la opción para sed. Ahora podemos usarlo con eval. Digamos que nuestro archivo se llama prueba. Usamos:
$ eval "sed" $(for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done) "test"
Respuesta4
paste -d : fileA fileB | sed 's/\([^:]*\):\([^:]*\)/s%\1%\2%/' > sed.script
sed -f sed.script SOURCE-FILE
SOURCE-FILE
Puede ser un archivo individual o varios archivos. El texto en el archivo A y el archivo B no puede contener dos puntos ni caracteres de porcentaje, pero puede contener caracteres en blanco.