Pergunta

Eu gostaria de usar Sed para expandir variáveis ??dentro de um arquivo.

Suponha que eu exportados uma variável VARIÁVEL = alguma coisa, e ter um arquivo de "teste" com o seguinte:

I'd like to expand this: "${VARIABLE}"

Eu tenho tentado comandos como o seguinte, mas sem sucesso:

cat test | sed -e "s/\(\${[A-Z]*}\)/`eval "echo '\1'"`/" > outputfile

O resultado é o "outputfile" com a variável ainda não expandido:

I'd like to expand this: "${VARIABLE}"

Ainda assim, correndo eval "echo '${VARIABLE}' em bash resultados do console no valor "algo" que está sendo ecoado. Além disso, eu testado e esse padrão é trully sendo correspondida.

A saída desejada seria

I'd like to expand this: "something"

Alguém pode lançar uma luz sobre isso?

Foi útil?

Solução

Considere a sua versão de teste:

cat test | sed -e "s/\(\${[A-Z]*}\)/`eval "echo '\1'"`/" > outputfile

A razão isso não funcionar é porque requer presciência por parte do shell. O script sed é gerado antes de qualquer padrão é acompanhado por sed, para que o shell não pode fazer esse trabalho para você.

Eu fiz isso de duas maneiras no passado. Normalmente, eu tive uma lista de variáveis ??conhecidas e seus valores, e eu fiz a substituição dessa lista:

for var in PATH VARIABLE USERNAME
do
    echo 's%${'"$var"'}%'$(eval echo "\$$var")'%g'
done > sed.script

cat test | sed -f sed.script > outputfile

Se você deseja mapear variáveis ??arbitrariamente, então você quer necessidade de lidar com todo o ambiente (em vez de uma lista fixa de nomes de variáveis, use a saída do env, devidamente editado), ou usar Perl ou Python vez.

Note que, se o valor de uma variável de ambiente contém uma barra na sua versão, você executar em problemas usando a barra como separador de campo no s /// notação. Eu usei o '%' desde relativamente poucas variáveis ??de ambiente usar isso - mas há alguns encontrados em algumas máquinas que contêm '% dos personagens e assim uma solução completa é mais complicado. Você também precisa se preocupar com barras invertidas no valor. Você provavelmente tem que usar algo como '$(eval echo "\$$var" | sed 's/[\%]/\\&/g')' para escapar as barras invertidas e símbolos por cento no valor da variável de ambiente. rugas final: algumas versões do sed tem (ou teve) uma capacidade limitada para o tamanho do roteiro - versões mais antigas do HP-UX tinha um limite de cerca de 100. Eu não tenho certeza se isso ainda é um problema, mas como foi recentemente como há 5 anos.

A adaptação simplória do script original lê:

env |
sed 's/=.*//' |
while read var
do
    echo 's%${'"$var"'}%'$(eval echo "\$$var" | sed 's/[\%]/\\&/g')'%g'
done > sed.script

cat test | sed -f sed.script > outputfile

No entanto, a melhor solução usa o fato de que você já tem os valores na saída do env, então podemos escrever:

env |
sed 's/[\%]/\\&/g;s/\([^=]*\)=\(.*\)/s%${\1}%\2%/' > sed.script
cat test | sed -f sed.script > outputfile

Esta é completamente seguro porque o shell não avalia qualquer coisa que não deve ser avaliada - você tem que ser tão cuidadosos com metacaracteres shell em valores variáveis. Esta versão só pode eventualmente topar com algum problema, se alguma saída de env é mal formado, eu acho.

Cuidado -. Escrever scripts sed com sed é uma ocupação esotérico, mas que ilustra o poder de boas ferramentas

Todos estes exemplos são negligentes em não limpar o arquivo temporário (s).

Outras dicas

Talvez você pode obter perto sem usar sed:

$ echo $VARIABLE
something
$ cat test
I'd like to expand this: ${VARIABLE}
$ eval "echo \"`cat test`\"" > outputfile
$ cat outputfile
I'd like to expand this: something

Vamos variável shell interpolação fazer o trabalho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top