Como faço para usar variáveis em um comando sed?

Tentei o seguinte código para substituir QQ com ZZ, mas não faz o que eu quero:

var1=QQsed -i 's/$var1/ZZ/g' $file

No entanto, este código faz o que eu quero:

sed -i 's/QQ/ZZ/g' $file

Como faço para usar variáveis em sed?

O shell é responsável pela expansão de variáveis. Quando você usa aspas simples para strings, seu conteúdo será tratado literalmente, então sed agora tenta substituir cada ocorrência do literal $var1 por ZZ.

Usando aspas duplas

Use aspas duplas para fazer o shell expandir variáveis enquanto preserva o espaço em branco:

sed -i "s/$var1/ZZ/g" "$file"

Quando você exige o caractere de cotação na string de substituição, você tem que precedê-lo com uma barra invertida que será interpretada pelo shell. No exemplo a seguir, a string quote me será substituído por "quote me" (personagem & é interpretado por sed):

sed -i "s/quote me/\"&\"/" "$file"

Usando aspas simples

Se você tiver muitos meta-caracteres de shell, considere usar aspas simples para o padrão e aspas duplas para a variável:

sed -i 's,'"$pattern"',Say hurrah to &: \0/,' "$file"

Observe como eu uso s,pattern,replacement, em vez de s/pattern/replacement/, Eu fiz isso para evitar interferência com o / em \0/.

Exemplo

O shell então executa o comando acima sed com os próximos argumentos (assumindo pattern=bert e file=text.txt):

-is,bert,Say hurrah to &: \0/,text.txt

Se file.txt conteudo bert, a saída será:

Say hurrah to bert: \0/

Podemos usar variáveis em sed usando aspas duplas:

sed -i "s/$var/r_str/g" file_name

Se você tem uma barra / na variável, em seguida, use separador diferente, como abaixo:

sed -i "s|$var|r_str|g" file_name

Para expandir (trocadilho pretendido) em @ resposta de mani,

  • esta solução funcionará para expressões regulares alimentadas a outros comandos, como perl
  • use aspas duplas em torno do regex (sim, mesmo em sistemas Unixy) para expandir a variável conforme o esperado
  • | pode aparecer no valor da sua variável também, então não tenha medo de tentar outros delimitadores

veja minha resposta neste post seu

relacionados: Escape a string for a sed replace pattern - Stack Overflow