Cómo reemplazar una lista de cadenas por otra lista

Cómo reemplazar una lista de cadenas por otra lista

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 fileAy fileBtienen 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-FILEPuede 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.

información relacionada