Tengo una serie de "opciones" de un comando.
my_array=(option1 option2 option3)
Quiero llamar a este comando en un script bash, usando los valores de la matriz como opciones. Entonces, se command $(some magic here with my_array) "$1"
convierte en:
command -option1 -option2 -option3 "$1"
¿Cómo puedo hacerlo? ¿Es posible?
-
al comienzo de cada palabramy_array
?Respuestas:
Preferiría una
bash
forma simple :Una razón para esto son los espacios. Por ejemplo si tienes:
Las
sed
soluciones basadas lo transformarán en-option1 -option2 -with -space -option3
(longitud 5), pero labash
expansión anterior lo transformará en-option1 -option2 with space -option3
(longitud todavía 3). Raramente, pero a veces esto es importante, por ejemplo:fuente
somevar=("${my_array[@]/#/-}")
(Nota del paréntesis alrededor del valor.) Entonces, por supuesto, usted tiene que mantener su manejo como un array cuando se la usa:echo "${somevar[@]}"
. En cuanto a las funciones, allí estás demasiado limitado por las posibilidades del lenguaje. Puede pasar un array:somefunc "${my_array[@]/#/-}"
, a continuación, en el interior se tienen en$@
:function somefunc() { echo "$@"; }
. Pero lo mismo$@
también contendrá los otros parámetros, si existen, y no hay otra forma de devolver la matriz modificada que stdout.@
como subíndice de matriz? Lo probé con zsh 5.5.1 y la única diferencia es que noté que zsh solo tenía el prefijo de cada elemento cuando se escribía como${my_array[@]/#/-}
, mientras que bash también lo hacía para el*
subíndice.No procesé que estaba en una matriz y estaba pensando en espacios en blanco separados en una cadena. Esta solución funcionará con eso, pero dado que es una matriz, vaya con la solución de manatwork (
@{my_array[@]/#/-}
).Esto no es tan malo con
sed
una subshell. Lo fácil que es la expresión regular depende de lo que pueda garantizar sobre las opciones. Si las opciones son todas una "palabra" (a-zA-Z0-9
solo),\<
bastará con un simple límite de palabra inicial ( ):Si sus opciones tienen otros caracteres (muy probablemente
-
), necesitará algo un poco más complejo:^
coincide con el comienzo de la línea,[ \t]
coincide con un espacio o tabulación,\|
coincide con cualquier lado (^
o[ \t]
),\(
\)
agrupa (para\|
) y almacena el resultado,\<
coincide con el inicio de una palabra.\1
comienza el reemplazo manteniendo la primera coincidencia de los parens (\(\)
) y,-
por supuesto, agrega el guión que necesitamos.Estos funcionan con gnu sed, si no funcionan con los suyos, hágamelo saber.
Y si va a usar lo mismo varias veces, es posible que desee calcularlo una vez y almacenarlo:
fuente
gsed
(lo instalé usandohomebrew
). Otra cosa: en lugar deecho $my_array
, tenía que hacerecho ${my_array[@]}
para obtener todos los elementosmy_array
:echo $my_array
me estaba dando solo el primer elemento. Pero gracias por la respuesta y la explicación de la expresión regular, especialmente sobre el "límite de palabras", esto es extremadamente útil. :)[ $(echo x | sed 's/\</y/') == "yx" ] || exit
.fuente