Use o comando sed com variáveis

Use o comando sed com variáveis

Tentei todas as soluções possíveis disponíveis no Stack Overflow e seus sites relacionados, mas não encontrei nenhuma solução. Passei um tempo razoável nesse assunto e finalmente estou postando essa pergunta.

Quero usar o sedcomando com variáveis ​​​​shell. Meu script é bem simples:

## string to replace is the text after comma in the variable pc.
to_replace=${pc#*,}
echo $to_replace

##text to be replaced by the following line
replace_with="PARTITIONED BY ($pc1);"
echo $replace_with

## use sed command to replace.
sed "s@$to_replace@$replace_with@" $entry  ## $entry is the variable that contains the file name

Os dois echocomandos fornecem as seguintes saídas, respectivamente:

PARTITIONEDED BY (date_key );  ## the text I want to be replaced
PARTITIONED BY ( date_key int );  ## the text I want to replace with

Eu recebo um erro:

sed: -e expression #1, char 2: unterminated `s' command

ou o texto não é substituído.

Alguém por favor ajude. Estou usando o Centos 6 (se isso importa). Desde já, obrigado!

Responder1

sed: -e expression #1, char 2: unterminated `s' command

A mensagem de erro diz que o erro acontece no segundo caractere, o que parece curioso. Posso reproduzir isso colocando uma nova linha no início da primeira variável:

$ a=$'\nfoo'
$ b='bar'
$ sed "s@$a@$b@"
sed: -e expression #1, char 2: unterminated `s' command

Uma nova linha sem escape encerra o comando sed. Colocar a nova linha posteriormente acausaria o erro em um caractere posterior.

Você imprimiu ambas as variáveis ​​anteriormente no script, mas elas não foram citadas, portanto, qualquer espaço em branco inicial nelas teria sido removido e o espaço em branco no meio seria exibido como espaços únicos.

Verifique o que suas variáveis ​​realmente contêm, com algo como isto:

printf ">%s<\n" "$to_replace"
printf "%q\n" "$to_replace"

O último é um recurso do Bash que exibe a string citada de uma forma que o Bash aceita como entrada. set -xtambém mostraria o que vai para a linha de comando do sed, mas você precisaria observar a nova linha literal de sua saída.

Portanto, se uma única nova linha inicial for tudo o que existe, você poderá removê-la no início do script:

to_replace=${pc#*,}
to_replace=${to_replace#$'\n'}

(Você pode combiná-los em um, mas etapas separadas funcionam mesmo que a nova linha não esteja lá.)

Responder2

Experimente isso

sed -i -e "s@$to_replace@$replace_with@g" "$entry"

onde

  • -isignifica substituir "no lugar". Se você não usar, -isubstituir estará na saída padrão.

informação relacionada