Bash enquanto pesquisa em loop e substitui usando sed

3

Eu tenho um problema com meu script a seguir (essa é a parte relevante dele):

#!/bin/bash

OLD=(
"_MAIN1_"
"_MAIN2_"
)

NEW=(
"#111"
"#222"
)

length=${#OLD[*]}

i=0

while (( i < length ))
do
  sed -e "s/${OLD[$i]}/${NEW[$i]}/g" oldfile.txt > newfile.txt

  #sed -e 's/_MAIN1_/#111/g' oldfile.txt > newfile.txt  # this works

  # Another way that does not work
  #sed -e 's/'"${OLD[$i]}"'/'"${NEW[$i]}"'/g' oldfile.txt > newfile.txt

  ((i++))
done

exit 0

Meu objetivo é substituir as strings em um arquivo e salvá-lo em um novo. As strings "old" e "new" são armazenadas em uma matriz.

Eu tentei muitas coisas e brinquei com aspas simples e duplas - mas nada funcionou. Quando eu echo as variáveis eu recebo as seqüências corretas dentro do loop. Se duas strings explícitas forem configuradas no comando sed , isso funcionará bem para isso.

Os padrões de sequência seguem aqueles em meus arrays de exemplo ('new' contém o sublinhado "_" e 'old' contém a hashtag "#").

Estou executando o bash em uma caixa do Ubuntu 16.04.

Muito obrigado!

    
por mazienho 20.05.2017 / 04:23

3 respostas

2

Crie um script sed que faça todas as substituições e, em seguida, aplique o script sed ao seu arquivo.

for (( i=0; i<${#OLD[@]}; ++i )); do
        printf 's/%s/%s/g\n' "${OLD[$i]}" "${NEW[$i]}"
done >script.sed

sed -f script.sed inputfile >outputfile && mv outptufile inputfile && rm script.sed

Desta forma, você limita o número de vezes que você precisa analisar o arquivo de entrada para um.

Para os dados fornecidos em OLD e NEW , o script sed será gerado como

s/_MAIN1_/#111/g
s/_MAIN2_/#222/g
    
por 20.05.2017 / 13:54
0

Seu script inteiro (que não funciona) pode ser substituído por uma única linha:

sed 's/_MAIN\([12]\)_/#/g' oldfile.txt > newfile.txt

Ou mais, mas de forma equivalente:

sed 's/_MAIN1_/#111/g;s/_MAIN2_/#222/g' oldfile.txt > newfile.txt

Existem várias outras maneiras de conseguir isso, dependendo do seu caso de uso real (por exemplo, de onde vêm os dados, como são realmente os valores, o que você está tentando fazer com o dados, etc.).

    
por 20.05.2017 / 05:28
-1

Graças ao comentário do Rakesh Sharma , eu consegui resolver isso usando o sinal -i em comando sed. Antes do loop, o arquivo original é salvo:

cp oldfile.txt oldfile.backup
while (( i < length ))
do
  sed -i -e 's/'"${OLD[$i]}"'/'"${NEW[$i]}"'/g' oldfile.txt
  ((i++))
done

A próxima vez que eu usar o Perl para manipulações de strings.

Editar: Adicionado ((i++)) para evitar um loop infinito (Graças a Comentário de Kusalananda ).

    
por 20.05.2017 / 10:58