Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have an array of "options" of a command.

my_array=(option1 option2 option3)

I want to call this command in a bash script, using the values from array as options. So, command $(some magic here with my_array) "$1" becomes:

command -option1 -option2 -option3 "$1"

How can I do it? Is it possible?

share|improve this question
1  
So you want to add - to the beginning of each word in my_array? –  Kevin Jan 20 '12 at 3:19
    
@Kevin: Yes, and execute it. All lines are inside the same bash script. I'm asking this because these same options are going to be used in a lot of places inside the script, so instead of copying all of them around, I thought about an array. –  Somebody still uses you MS-DOS Jan 20 '12 at 3:43
    
It might seem pointless but if you are making big shell scripts maybe you should look into perl, this kind of thing is very easy to do there. –  alfa64 Jan 20 '12 at 6:29

3 Answers 3

up vote 7 down vote accepted

I would prefer a plain bash way:

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

One reason for this are the spaces. For example if you have:

my_array=(option1 'option2 with space' option3)

The sed based solutions will transform it in -option1 -option2 -with -space -option3 (length 5), but the above bash expansion will transform it into -option1 -option2 with space -option3 (length still 3). Rarely, but sometimes this is important, for example:

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
share|improve this answer
1  
this is much simpler, thanks @manatwork –  Nikhil Mulley Jan 21 '12 at 16:56
    
Indeed. +1 and changed as accepted. :) –  Somebody still uses you MS-DOS Jan 23 '12 at 4:52

I didn't process that it was in an array and was thinking whitespace-separated in a string. This solution will work with that, but given that it's an array, go with manatwork's solution (@{my_array[@]/#/-}).


This isn't too bad with sed and a subshell. Just how easy the regex is depends on what you can guarantee about the options. If the options are all one "word" (a-zA-Z0-9 only), then a simple beginning word boundary (\<) will suffice:

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

If your options have other characters (most likely -), you'll need something a bit more complex:

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

^ matches the beginning of the line, [ \t] matches a space or tab, \| matches either side (^ or [ \t]), \( \) groups (for the \|) and stores the result, \< matches the start of a word. \1 begins the replacement by keeping the first match from the parens (\(\)), and - of course adds the dash we need.

These work with gnu sed, if they don't work with yours, let me know.

And if you'll be using the same thing multiple times, you may want to just calculate it once and store it:

opts="$(echo $my_array | sed 's/\(^\|[ \t]\)\</\1-/g')"
...
command $opts "$1"
command $opts "$2"
share|improve this answer
    
This didn't work with Mac OS X sed, so I needed to use gsed (I installed using homebrew). Another thing: instead of echo $my_array, I needed to do echo ${my_array[@]} to get all items from my_array: echo $my_array was giving me only the first element. But thanks for the answer and the explanation of the regex, specially about "word boundary", this is extremely useful. :) –  Somebody still uses you MS-DOS Jan 20 '12 at 4:50
    
I would like to exit the script if the system's sed isn't compatible with this word boundary feature. How would I do it? Printing sed version and comparing it? From which version of sed this feature was added? –  Somebody still uses you MS-DOS Jan 20 '12 at 5:00
1  
@SomebodystillusesyouMS-DOS My first thought is to check directly whether it works - [ $(echo x | sed 's/\</y/') == "yx" ] || exit. –  Kevin Jan 20 '12 at 5:09
1  
This will break if any of the array elements contain special characters, most obviously and inexorably whitespace. –  Gilles Jan 20 '12 at 23:09
1  
@SomebodystillusesyouMS-DOS Gilles is right, you should change your accept to manatwork. –  Kevin Jan 21 '12 at 16:44
[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'
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.