Respostas:
Use um delimitador regex alternativo, pois sedpermite que você use qualquer delimitador ( incluindo caracteres de controle ):
sed "s~$var~replace~g" $file
$var
Uma resposta puramente bash: use a expansão do parâmetro para fazer o escape de qualquer barra invertida na variável:
var="/Users/Documents/name/file"
sed "s/${var//\//\\/}/replace/g" $file
${parameter/pattern/string}. Portanto, neste caso, o parâmetro é var, o padrão é /\/e a string é \\/. Todas as instâncias do padrão são substituídas porque o padrão começa com a /.
Usar /em sed como um delimitador entrará em conflito com as barras na variável quando substituída e, como resultado, você obterá um erro. Uma maneira de contornar isso é usar outro delimitador que seja exclusivo de todos os caracteres dessa variável.
var="/Users/Documents/name/file"
você pode usar o caractere octotorpe que se adapte à ocasião (ou qualquer outro caractere que não seja /para facilidade de uso)
sed "s#$var#replace#g"
ou
sed 's#$'$var'#replace#g'
isto é adequado quando a variável não contém espaços
ou
sed 's#$"'$var'"#replace#g'
É mais sensato usar o acima, uma vez que estamos interessados em substituir o que quer que esteja nessa variável apenas em comparação com aspas duplas de todo o comando, o que pode fazer com que seu shell interprete qualquer caractere que possa ser considerado um caractere especial de shell para o shell.
$varcontém ~, obviamente você precisará escolher um delimitador diferente. O erro "não terminado" parece que $varcontém uma nova linha; você pode consertá-lo fazendo escape de barra invertida a cada nova linha no valor, mas não acho que isso seja totalmente portátil. Em geral, isso não está relacionado ao problema de barras no valor.
sed -i "s~blah~$var~g" filecom aspas apenas em torno do sedscript real .
Esta é uma pergunta antiga, mas nenhuma das respostas aqui discute as operações, a não ser s/from/to/com muitos detalhes.
A forma geral de uma seddeclaração é
*address* *action*
onde o endereço pode ser um intervalo regex ou um intervalo de número de linha (ou vazio, caso em que a ação é aplicada a cada linha de entrada). Então por exemplo
sed '1,4d' file
irá deletar as linhas 1 a 4 (o endereço é o intervalo do número da linha 1,4e a ação é o dcomando deletar); e
sed '/ick/,$s/foo/bar/' file
irá substituir a primeira ocorrência de foopor barem qualquer linha entre a primeira correspondência na regex icke o final do arquivo (o endereço é o intervalo /ick/,$e a ação é o scomando substituto s/foo/bar/).
Neste contexto, se ickveio de uma variável, você poderia fazer
sed "/$variable/,\$s/foo/bar/"
(observe o uso de aspas duplas em vez de simples, para que o shell possa interpolar a variável e a necessidade de colocar o cifrão literal entre aspas duplas), mas se a variável contiver uma barra, você obterá um erro de sintaxe. (O shell expande a variável e, em seguida, passa a string resultante para sed; portanto, sedvê apenas o texto literal - não tem nenhum conceito das variáveis do shell.)
A solução é usar um delimitador diferente (onde obviamente você precisa ser capaz de usar um caractere que não pode ocorrer no valor da variável), mas ao contrário do s%foo%bar%caso, você também precisa de uma barra invertida antes do delimitador se quiser usar um delimitador do que o padrão /:
sed "\\%$variable%,\$s/foo/bar/" file
(entre aspas simples, uma única barra invertida seria obviamente suficiente); ou você pode escapar separadamente de cada barra no valor. Esta sintaxe específica é apenas Bash:
sed "/${variable//\//\\/}/,\$s/foo/bar/" file
ou se você usar um shell diferente, tente
escaped=$(echo "$variable" | sed 's%/%\\/%g')
sed "s/$escaped/,\$s/foo/bar/" file
Para maior clareza, se $variablecontiver a string 1/2, os comandos acima seriam equivalentes a
sed '\%1/2%,$s/foo/bar/' file
no primeiro caso, e
sed '/1\/2/,$s/foo/bar/' file
no segundo.
Use Perl, onde as variáveis são cidadãos de primeira classe, não apenas macros de expansão:
var=/Users/Documents/name/file perl -pe 's/\Q$ENV{var}/replace/g' $file
-p lê a entrada linha por linha e imprime a linha após o processamento\Qcita todos os metacaracteres na seguinte string (não necessária para o valor apresentado aqui, mas necessária se o valor contiver [ou alguns outros valores especiais para expressões regulares)