Eu tenho muitos arquivos diferentes com uma string neles. Preciso substituir esta string por um caminho, embora o caminho contenha espaços em branco. Até agora, eu tenho isso:
for a in files_[a-z][a-z]_all\.conf ; do
fileWithPath="~/Downloads/files_config_linux/auth-user-pass files_userpass.txt"
otherOne="auth-user-pass mullvad_userpass.txt"
sed -i 's|'$otherOne'|'$fileWithPath'|g' $a
done
Mas eu entendo
sed: -e expressão #1, caractere 16: comando `s' não terminado
Minha dúvida é como substituir essa string corretamente, pelo meu caminho que possui espaço em branco.
Obrigado !
Sua expressão
produz a string sem aspas
que é então analisado em várias palavras nos caracteres de espaço. O primeiro deles,
é então passado para
sed
o qual reclama, com razão, da falta do segundo|
separador.Para passar o
s
comando inteirosed
como um único argumento, você precisa citá-lo. A maneira mais fácil de fazer isso é colocar toda a expressão entre aspas duplas:O shell executa a substituição de variáveis entre aspas duplas, então isso produzirá a string entre aspas
que será então passado como um único argumento conforme
sed
pretendido.Também é uma boa prática colocar o argumento do nome do arquivo
$a
entre aspas duplas, para proteger contra caracteres de espaço no nome do arquivo, embora no seu caso não seja estritamente necessário, pois seu padrãofiles_[a-z][a-z]_all\.conf
não corresponderá a nenhum nome de arquivo que contenha espaços.Seu shell dividirá strings sem aspas (resultantes da expansão de parâmetro/variável no seu caso) em palavras em torno de valores em
IFS
... Consulte Divisão de palavras ... Isso é uma coisa.Seu shell pode passar argumentos de linha de comando com aspas modificadas para o programa invocado... e isso é outra coisa.
Dizem que " Ver algo uma vez é melhor do que ouvir falar cem vezes. " e " Fazer algo uma vez é melhor do que ver cem vezes. "
Se você habilitar rastreamentos de comando no shell Bash
set -x
e depois emitir osed
comando como você o possui:... você pode ver como sua linha de comando é realmente construída e passada para o
sed
programa e como você pode ver, seu script fornecido é dividido em várias partes (com aspas adicionadas) ... e no que dizsed
respeito ao programa apenas o primeiro conjunto de aspas correspondentes é considerado como um script's|auth-user-pass'
e os seguintes nem sequer são considerados ou adicionados ao script, uma vez que no-e
é fornecido (para indicar comandos aninhados, embora-e
exija comandos sintaticamente corretos para funcionar ) e, portanto, de fato, os
comando não foi encerrado nesse contexto ... daí a mensagem:Agora que você pode ver os bastidores, compare o acima com:
ou:
... e isso deveria ser suficiente para "ver" e "fazer" para descobrir o que está acontecendo.