Como substituir uma lista de strings por outra lista

5

Eu tenho um arquivo que tem (muitas) cadeias de caracteres que gostaria de substituir, então pensei em usar um comando simples como:

sed 's/string1/string2/g' file1 > out  

No entanto, existem muitas cadeias para que sejam repetidas manualmente. Então eu fiz uma lista de todas as strings a serem substituídas, cada uma em uma linha, e nomeei o arquivo A. Então fiz uma lista de todas as strings de substituição, e nomeei o arquivo B

.

Existe uma maneira de fazer algo como:

sed 's/line i of file A/line i of file B/g' file1 > out

para cada linha de arquivo A?

    
por Asasuser 12.01.2013 / 00:01

4 respostas

3

Seria mais fácil criar um arquivo com as strings de entrada e de substituição na mesma linha (supondo que nem as strings de entrada nem de substituição contenham espaços). Então você pode fazer algo simples como:

while read n k; do sed -i 's/$n/$k/g' file1; done < fileA

EDITAR:

Depois de ver a resposta de Nykakin, percebi que você pode fazer a mesma coisa com os dois arquivos que você tem combinando a sugestão dele com a minha:

paste fileA fileB | while read n k; do sed -i 's/$n/$k/g' file1; done 
    
por 12.01.2013 / 02:24
1

Esta é basicamente sua primeira ideia, mas com os comandos de substituição colocados em um arquivo, eles são mais gerenciáveis:

tmpfile=/tmp/Asasuser.$$
exec 3< fileA
exec 4< fileB
while read –r astring <&3
do
        read –r bstring <&4
        echo "s/$astring/$bstring/" >> "$tmpfile"
done
exec 3<&- 4<&-
sed –f "$tmpfile" file1 > out
rm –f "$tmpfile"

Isso pressupõe que fileA e fileB tenham o mesmo número de linhas (e que esse número seja maior que zero) e que nenhum deles tenha nenhum caractere / sem escape.

    
por 12.01.2013 / 00:26
1

Podemos apenas gerar o comando de que precisamos. Digamos que os arquivos com listas sejam chamados de lista e listb. Então podemos usar:

$ for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done

para gerar a opção para sed. Agora podemos usá-lo com eval. Vamos dizer que nosso arquivo é chamado de teste. Nós usamos:

$ eval "sed" $(for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done) "test"
    
por 12.01.2013 / 02:26
0
paste -d : fileA fileB | sed 's/\([^:]*\):\([^:]*\)/s%%%/' > sed.script
sed -f  sed.script SOURCE-FILE

O SOURCE-FILE pode ser um arquivo individual ou vários arquivos. O texto no arquivo A e no arquivo B não pode conter caracteres de dois-pontos ou de porcentagem, mas pode conter caracteres em branco.

    
por 12.01.2013 / 13:40