Transforma uma matriz em argumentos de um comando?

33

Eu tenho uma matriz de "opções" de um comando.

my_array=(option1 option2 option3)

Eu quero chamar este comando em um script bash, usando os valores da matriz como opções. Então, command $(some magic here with my_array) "$1" se torna:

command -option1 -option2 -option3 "$1"

Como posso fazer isso? É possível?

    
por Somebody still uses you MS-DOS 20.01.2012 / 04:03

3 respostas

34

Eu preferiria uma maneira simples de bash :

command "${my_array[@]/#/-}" "$1"

Uma razão para isso são os espaços. Por exemplo, se você tiver:

my_array=(option1 'option2 with space' option3)

As soluções baseadas em sed irão transformá-lo em -option1 -option2 -with -space -option3 (comprimento 5), mas a expansão bash acima irá transformá-lo em -option1 -option2 with space -option3 (comprimento ainda 3). Raramente, mas às vezes isso é importante, por exemplo:

bash-4.2$ my_array=('Ffoo bar' 'vOFS=fiz baz')
bash-4.2$ echo 'one foo bar two foo bar three foo bar four' | awk "${my_array[@]/#/-}" '{print$2,$3}'
 two fiz baz three
    
por 20.01.2012 / 08:53
1

Eu não processei que estava em uma matriz e estava pensando em espaços em branco separados em uma string. Essa solução funcionará com isso, mas, como é uma matriz, use a solução manatwork ( @{my_array[@]/#/-} ).

Isso não é muito ruim com sed e um subshell. O quão fácil é a regex depende do que você pode garantir sobre as opções. Se as opções forem todas uma "palavra" ( a-zA-Z0-9 apenas), então um simples limite de palavras iniciais ( \< ) será suficiente:

command $(echo $my_array | sed 's/\</-/g') "$1"

Se suas opções tiverem outros caracteres (provavelmente - ), você precisará de algo um pouco mais complexo:

command $(echo $my_array | sed 's/\(^\|[ \t]\)\</-/g') "$1"

^ corresponde ao início da linha, [ \t] corresponde a um espaço ou guia, \| corresponde a qualquer um dos lados ( ^ ou [ \t] ), \( \) groups (para \| ) e armazena o resultado, \< corresponde ao início de uma palavra. começa a substituição mantendo a primeira correspondência dos parêntesis ( \(\) ), e - adiciona o traço que precisamos.

Esse trabalho com o gnu sed, se eles não funcionam com o seu, me avise.

E se você estiver usando a mesma coisa várias vezes, talvez queira apenas calculá-la uma vez e armazená-la:

opts="$(echo $my_array | sed 's/\(^\|[ \t]\)\</-/g')"
...
command $opts "$1"
command $opts "$2"
    
por 20.01.2012 / 04:38
0
[srikanth@myhost ~]$ sh sample.sh 

-option1 -option2 -option3

[srikanth@myhost ~]$ cat sample.sh

#!/bin/bash

my_array=(option1 option2 option3)

echo ${my_array[@]} | sed 's/\</-/g'
    
por 20.01.2012 / 05:53