0

I have a parse a command line argument in shell script as follows:

cmd --a=hello world good bye --b=this is bash script

I need the parse the arguments of "a" i.e "hello world ..." which are seperated by whitespace into an array.

i.e a_input() array should contain "hello", "world", "good" and "bye".

Similarly for "b" arguments as well.

I tried it as follows:

--a=*)
      a_input={1:4}
      a_input=$@
for var in $a_input
    #keep parsing until next --b or other argument is seen
done

But the above method is crude. Any other work around. I cannot use getopts.

Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
Kailash Akilesh
  • 173
  • 2
  • 2
  • 7
  • Possible duplicate? http://stackoverflow.com/questions/17094086/passing-arguments-with-spaces-between-bash-script – ventsyv Mar 04 '15 at 22:20
  • 2
    A better avenue of attack would be to require users to quote the multi-word arguments: `cmd --a='hello world good bye' --b='this is bash script'`. That would be far more idiomatic. – John Kugelman Mar 04 '15 at 22:55

2 Answers2

1

The simplest solution is to get your users to quote the arguments correctly in the first place.

Barring that you can manually loop until you get to the end of the arguments or hit the next --argument (but that means you can't include a word that starts with -- in your argument value... unless you also do valid-option testing on those in which you limit slightly fewer -- words).

Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
0

Adding to Etan Reisners answer, which is absolutely correct:

I personally find bash a bit cumbersome, when array/string processing gets more complex, and if you really have the strange requirement, that the caller should not be required to use quotes, I would here write an intermediate script in, say, Ruby or Perl, which just collects the parameters in a proper way, wraps quoting around them, and passes them on to the script, which originally was supposed to be called - even if this costs an additional process.

For example, a Ruby One-Liner such as

system("your_bash_script here.sh '".(ARGV.join(' ').split(' --').select {|s| s.size>0 }.join("' '"))."'")

would do this sanitizing and then invoke your script.

user1934428
  • 19,864
  • 7
  • 42
  • 87
  • 1
    That's effectively just the manual loop (done automatically) and this loses the internal `--`. – Etan Reisner Mar 05 '15 at 17:04
  • You are right - I forgot to put back the dashes (though this is trivial to add). Of course it is a loop internally, but from a programmer's viewpoint, you "act as an array" as a whole, which IMO makes it easier to understand (though this is a matter of taste). My main point was however: The more intelligence you need to put into your program, the less suitable bash becomes as a general programming language, and it might be worth looking at alternatives. – user1934428 Mar 06 '15 at 06:58