Por que esta solução OSX / BSD / sed não está funcionando?

3

Portanto, o sed se comporta de maneira diferente, dependendo de se é a versão do OSX / BSD ou GNU.

O OSX requer

sed -i '' <pattern> <file>

enquanto isso funciona com o GNU sed:

sed -i <pattern> <file>

Então eu tenho isso:

darwin=false;
case "$(uname)" in
    Darwin*) darwin=true ;;
esac

if $darwin; then
    sedi="sed -i '' "
else
    sedi="sed -i"
fi

E então eu tento chamá-lo no OSX

$sedi "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.java

E funciona, exceto por criar um arquivo de backup chamado Version.java ''.

Não sei por que isso não está funcionando porque, se eu fizer isso explicitamente na CLI:

sed -i '' "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.java

Funciona sem criar o arquivo de backup.

Alguma opinião?

    
por jshort 08.04.2014 / 22:51

2 respostas

1

Quando você expande a variável sedi , o que está acontecendo é que o '' é passado para sed como um argumento, em vez disso, para criar um argumento vazio conforme o esperado.

A melhor maneira de ver isso é tornar sua variável sedi uma matriz:

if $darwin; then
    sedi=(sed -i '')
else
    sedi=(sed -i)
fi

E use assim:

"${sedi[@]}" "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.java

Caso contrário, acho que a única maneira de transformar seu '' em um argumento real vazio é usar eval com sua declaração original:

eval $sedi '"s/VERSION =.*;/VERSION = \"${lver}\";/g"' Version.java

No entanto, esta é uma solução um pouco desagradável, uma vez que você tem que adicionar uma camada extra de aspas / escapes para o resto do comando. Também é geralmente uma boa (e segura) prática evitar o uso de eval quando possível.

Atualizar

Como comentado abaixo, a criação de uma função funcionará. Na mesma faixa, um alias é provavelmente o método mais curto:

if $darwin; then
    alias sedi="sed -i ''"
else
    alias sedi="sed -i"
fi

Simplificando o uso:

sedi "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.java
    
por 08.04.2014 / 23:30
1

Defina uma função de shell que envolva sed :

case "$(uname)" in
    Darwin*) sed () { command sed -i '' "$@"; } ;;
    *)       sed () { command sed -i "$@"; } ;;
esac
    
por 09.04.2014 / 15:46

Tags