Criando uma variável com sed no ksh

3

Estou usando o Ksh88 em uma máquina Solaris 10.

Se eu fizer o seguinte:

foo="one two three"
for i in $foo; do
    echo $i;
done

O script é executado conforme o esperado:

$ ./script.ksh
one
two
three

No entanto, se eu substituir o loop com isso:

foo="one two three"
for i in $(sed -e 's/bar/$foo/' <(echo $1));
do
    echo $i
done

Eu executo e é isso que eu recebo:

$ ./script.ksh bar
$foo

Como posso fazer com que for expanda o resultado do comando sed em uma variável?

    
por rahmu 21.02.2012 / 11:59

2 respostas

2

sed -e 's/bar/$foo/' <(echo $1) imprime $foo . O resultado de uma expansão de comando não está sujeito ao processamento de sintaxe do shell. Ele está sujeito apenas à geração de nome de arquivo (dividindo em palavras) o nome do arquivo (ou seja, globbing), quando você o usa dessa forma fora de aspas duplas.

Em qualquer shell, se você tiver o nome de uma variável em outra variável, poderá obter o valor dessa variável com eval .

variable_name=$(sed -e 's/bar/foo/' <(echo $1))
case $variable_name in
  *[!0-9A-Z_a-z]*) echo 1>&2 "Invalid variable name: $variable_name"; exit 3;;
esac
eval variable_value="\${$variable_name}"
for i in $variable_value; do …

Observe que $variable_value não apenas divide o valor em partes delimitadas por espaços em branco, mas também executa globbing (ou seja, expande curingas em nomes de arquivos) nas partes. Para desativar a globbing, ligue antes para set +f .

No ksh93, há um sinalizador especial que você pode usar ao definir uma variável var , que informa ao shell que o valor da variável é um nome de variável e que $var deve expandir para o valor da variável cujo nome é $var . Além disso, você deve fazer foo uma matriz, já que é realmente uma lista de strings e não uma string.

foo=(one two three)
typeset -n variable_name="$(sed -e 's/bar/foo/' <(echo $1))"
for i in "${variable_name[@]}"; do …
    
por 22.02.2012 / 02:32
0
foo=$(echo "$foo" | sed 's/[\\/]/\&/g') # only required if $foo can contain one of \/
set +f     # only required if $foo contains one of \[*?
for i in $(echo "$1" | sed -e "s/bar/$foo/"); do
    echo $i
done
    
por 21.02.2012 / 14:16