Por que um comando sed funciona interativamente, mas não no meu script? [duplicado]

1

O comando SED não está substituindo no bash no Debian, mas funciona na linha de comando.

Funciona na linha de comando:

sed -i 's|/dev/disk/by-label/SR6D4|/dev/disk/by-label/SR4D4|g' /etc/my/config.xml

Não está funcionando no script bash, não substitui a string:

from="SR6D4"
to="SR4D4"
path_from="/dev/disk/by-label/${from}"
path_to="/dev/disk/by-label/${to}"
echo "sed -i 's|${path_from}|${path_to}|g' $file"
sed -i 's|${path_from}|${path_to}|g' $file

Por que não substituir string no arquivo ao usar sed no bash?

    
por klor 22.01.2018 / 07:57

2 respostas

2

As variáveis do shell não serão expandidas entre aspas simples. (É uma espécie de que as citações são para.)

sed -i "s|${path_from}|${path_to}|g" "$file"

deve funcionar melhor. (Eu adicionei aspas duplas em torno de $file apenas no caso do seu nome de arquivo já conter espaços.)

    
por 22.01.2018 / 08:04
1

Como mencionado anteriormente, você tem problema com citações. Mas há algumas opiniões sobre a substituição de string no arquivo. Veja abaixo.

É uma má ideia substituir a sequência em arquivo porque não é seguro. Há uma pequena probabilidade de perda de dados do arquivo durante a alteração.

Você pode tentar fazer o backup do arquivo antes de alterar:

cp /path/to/file{,.backup}
sed -i 'place your pattern here' /path/to/file

e você obterá o arquivo com o nome file.backup .

Você precisa se lembrar: se o seu arquivo estiver danificado e você irá apagá-lo e substituí-lo - o arquivo terá um inode diferente e perderá todos os hard links.

O segundo método de segurança:

mv /path/to/file{,.backup}; 
cat /path/to/file.backup | sed 'place your pattern here' > /path/to/file

O próximo ponto. Como o bashFAQ pensa :

Embedding shell variables in sed commands is never a good idea

É por isso que você precisa usar as opções awk with -v . Seu script pode ser assim:

from="SR6D4"
to="SR4D4"
path_from="/dev/disk/by-label/${from}"
path_to="/dev/disk/by-label/${to}"
sed -i 's|${path_from}|${path_to}|g' $file
mv $file{,.backup}
cat "${file}.backup" | awk -v awkfrom="$path_from" -v awkto="$path_to" '{gsub(awkfrom,awkto)}' > $file
    
por 22.01.2018 / 11:04