Se for uma linha e apenas uma linha para substituir, recomendo que você prefixe o arquivo com a linha de substituição usando printf , armazenando a primeira linha no espaço de retenção de sed e soltando-a conforme necessário. Dessa forma, você não precisa se preocupar com caracteres especiais. (A única suposição aqui é que $VAR contém uma única linha de texto sem nenhuma nova linha, que é o que você disse nos comentários.) Além de novas linhas, o VAR poderia conter qualquer coisa e isso trabalhar independentemente.
VAR=whatever
{ printf '%s\n' "$VAR";cat somefile; } | sed '1{h;d;};/KEYWORD/g'
printf '%s\n' imprimirá o conteúdo de $VAR como uma string literal, independentemente de seu conteúdo, seguido por uma nova linha. ( echo fará outras coisas em alguns casos, por exemplo, se o conteúdo de $VAR começar com um hífen - ele será interpretado como um sinalizador de opção sendo passado para echo .)
As chaves são usadas para pré-adicionar a saída de printf ao conteúdo de somefile à medida que é passado para sed . O espaço em branco que separa as chaves por si só é importante aqui, assim como o ponto-e-vírgula antes da chave de fechamento.
1{h;d;}; como um comando sed armazenará a primeira linha do texto no espaço hold de sed , então d elete a linha (ao invés de imprimi-lo). / p>
/KEYWORD/ aplica as seguintes ações a todas as linhas que contêm KEYWORD . A ação é g et, que obtém o conteúdo do espaço de armazenamento e o coloca no lugar do espaço padrão - em outras palavras, toda a linha atual. (Isto não é para substituir apenas parte de uma linha.) A propósito, o espaço de armazenamento não é esvaziado, apenas copiado para o espaço padrão, substituindo qualquer está lá.
Se você quiser ancorar seu regex, ele não corresponderá a uma linha que apenas contém KEYWORD, mas apenas uma linha em que não há mais nada na linha, exceto KEYWORD , adicione um início de âncora de linha ( ^ ) e âncora de fim de linha ( $ ) ao seu regex:
VAR=whatever
{ printf '%s\n' "$VAR";cat somefile; } | sed '1{h;d;};/^KEYWORD$/g'