sed com variáveis contendo /

0

eu tenho um arquivo de texto contendo algum conteúdo como esse,

some content  
replace content  
other content

e eu tenho algumas variáveis, parecendo assim:

PATH="/path/to/scriptdir"
PARAMETERS="para1 para2"
FILETOCHANGE="/foo/bar"

Agora eu quero substituir o conteúdo no arquivo de texto que começa com substituir , pelo conteúdo das variáveis PATH e PARÂMETROS . O arquivo de texto deve ficar assim, após a substituição:

some content
/path/to/scriptdir/script para1 para2
other content

Eu apenas tentei alguns comandos sed, mas sempre recebo um erro. Por exemplo

sed -i "s/^replace.*$/$PATH/script $PARAMETERS/g" $FILETOCHANGE
sed: -e expression #1, char 12: unknown option to 's'

ou

sed -i "s|^replace.*$|$PATH/script $PARAMETERS|g" $FILETOCHANGE
sed: -e expression #1, char 58: unterminated 's' command

Você pode me dizer o que estou fazendo de errado?

    
por michaelgr 27.09.2018 / 11:24

2 respostas

1

A solução final é mudar de sed para Perl, que lida com variáveis como cidadãos de primeira classe, não como macros para expandir como o shell.

path=/path/to/scriptdir parameters="para1 para2" perl -i~ -pe \
    's|^replace.*$|$ENV{path}/script $ENV{parameters}|g' -- "$filetochange"
  • -p lê a linha de entrada por linha e imprime cada linha depois de processá-la
  • o %ENV hash contém as variáveis de ambiente, atribuindo a elas no início de um comando as faz exportadas para o comando
  • s/// (altere os delimitadores como quiser) funciona de forma semelhante ao sed, veja perlop
por 27.09.2018 / 11:33
1

(1) não use a variável PATH para isso. Tem um significado especial para o shell. Eu escolho SCRIPTDIR aqui:

SCRIPTDIR="/path/to/scriptdir"
PARAMETERS="para1 para2"
FILETOCHANGE="/foo/bar"

(2) Você não precisa de uma barra ( / ) per se no comando de substituição do sed: s#this#that# ou s|this|that| funciona assim como s/this/that/g . Sed apenas usa o caractere diretamente após o s como o separador para o resto do comando s (substitute). Você pode usar isso para evitar o problema com as barras no padrão e na string de substituição: quando você usa, por exemplo, | como um separador, as barras não têm nenhum significado especial para o sed.

Então, isso funcionará:

sed "s%^replace.*$%$SCRIPTDIR/script $PARAMETERS%g" $FILETOCHANGE
    
por 27.09.2018 / 11:58