Começando com a primeira tarefa, apenas execute a alteração para {}
:
printf '%s' '{$aaa} \{$bbb} \{$ccc} {$ddd' | sed 's/{$\([^}]*\)}/${}/g'
Isto é, tudo após o {$
até o fechamento }
é colocado em \(\)
, para que possamos referenciá-lo na string de substituição como . Saída:
${aaa} \${bbb} \${ccc} {$ddd
Agora, sobre o escape da barra invertida. Sua solução funciona para \{$aaa}
(não toque) e \{$aaa}
(substituir), mas e quanto a \\{$aaa}
? Ele executará a alteração, o que provavelmente não é desejado.
Por isso, sugiro se livrar de todas as barras duplas invertidas primeiro. Nós os substituímos por uma combinação de caracteres que não pode fazer parte da string, #1
como exemplo, e alteramos de volta no final. Dessa forma, podemos nos concentrar apenas na barra invertida simples:
printf '%s' '{$aaa} \{$bbb} \{$ccc} \\{$eee} {$ddd' | sed 's/\\/#1/g;s/{$\([^}]*\)}/${}/g;s/#1/\\/g'
E, finalmente, podemos alterar \{
para #2
e substituí-lo no final para sair do nosso caminho:
printf '%s' '{$aaa} \{$bbb} \{$ccc} \\{$eee} {$ddd' | sed 's/\\/#1/g;s/\{/#2/g;s/{$\([^}]*\)}/${}/g;s/#2/\{/g;s/#1/\\/g'
Resultado: ${aaa} \${bbb} \{$ccc} \\{$eee} {$ddd
E isso funcionará para qualquer número de barras invertidas.
Mas se não houver nenhum caractere como #
você pode usar livremente? Você pode usar a nova linha, porque uma nova linha não pode fazer parte de uma linha. Já que você parece usar o GNU sed
, você pode fazer
printf '%s' '{$aaa} \{$bbb} \{$ccc} \\{$eee} {$ddd' | sed 's/\\/\n1/g;s/\{/\n2/g;s/{$\([^}]*\)}/${}/g;s/\n2/\{/g;s/\n1/\\/g'
Se isso for executado em um POSIX sed
, você precisará de um solução alternativa