0

I have to pass a command with its arguments in a scheduled task, while separating the arguments from the command. I used:

split(/(?=\s-)/)

to do this, but it won't work when the argument is not passed as -arg format.

Example of commands can be passed in format:

"ping http://www.google.com" here url is argument
"abc-abc -V"
"abc-abc -L c:\\folder name\\test.log"
'"C:\\Program Files\\example\\program.exe" -arg1 -arg2'
"C:\\Program Files\\example\\program.exe"

To make this more clear these commands are not passed as command line argument which can get in ARGV

The command gets set in command property which accepts input in string format

command '"C:\\Program Files\\example\\program.exe" -arg1 -arg2'

9
  • i think you should be looking for regular expression, the problem remaining is that your commands have many different syntaxes (command and args separated by space, but not for "C:\\Program Files" for example, then separated by '-' . Does it have to work with all syntaxes for your project ? Commented May 15, 2018 at 8:17
  • Can your command ever contain whitespace? If not, could you split on whitespace, treat the first token as the command and then format the arguments or options as appropriate? Commented May 15, 2018 at 8:51
  • @rwold spliting on whitespace will not work where command is like "C:\\Program Files\\example\\program.exe" Commented May 15, 2018 at 8:57
  • @AlexisDelahaye yes it should work with all examples Commented May 15, 2018 at 8:59
  • @vasu (1) Your example is not valid ruby syntax; I presume you meant /(?=\s-)/. (2) Why won't that example work by just splitting on space? Even in the comment above, I don't see how that will fail? (3) There's probably no need to "reinvent the wheel" here with some regex. There is a standard convention in almost all languages: The command line arguments are known as ARGV, which you can access in ruby as a constant. Ruby also provides ARGF, which works as a data stream. Commented May 15, 2018 at 9:36

3 Answers 3

3

Use Shellwords.split, from the standard library:

Shellwords.split("ping http:\\www.google.com here url is argument")
  #=> ["ping", "http:www.google.com", "here", "url", "is", "argument"]
Shellwords.split("abc-abc -V")
  #=> ["abc-abc", "-V"]
Shellwords.split("abc-abc -L c:\\folder name\\test.log")
  #=> ["abc-abc", "-L", "c:folder", "nametest.log"]
Shellwords.split('"C:\\Program Files\\example\\program.exe" -arg1 -arg2')
  #=> ["C:\\Program Files\\example\\program.exe", "-arg1", "-arg2"]
Shellwords.split('"C:\\Program Files\\example\\program.exe"')
  #=> ["C:\\Program Files\\example\\program.exe"]

No need to reinvent the wheel with a custom regex/splitter, or an external system call.

Sign up to request clarification or add additional context in comments.

7 Comments

I checked Shellwords and only worried where it takes on \\ from file path here Shellwords.split("abc-abc -L c:\\folder name\\test.log") #=> ["abc-abc", "-L", "c:folder", "nametest.log"]
@vasu That's not a valid example. In order to pass a pathname with spaces like this, you would need to wrap it in quotes - i.e. Shellwords.split("abc-abc -L 'c:\\folder name\\test.log'") #=> ["abc-abc", "-L", "c:\\folder name\\test.log"]
Are any of the examples I provided above different from the result you require? In which case, what result do you require? Are there other example inputs for which this won't work? What inputs? What result do you require?
This case also removes \\ here Shellwords.split("ping http:\\www.google.com here url is argument") #=> ["ping", "http:www.google.com", "here", "url", "is", "argument"]
@vasu Which website are you visiting with backslashes in the URL? :S Again, the's not a valid example - you would actually need to do Shellwords.split("ping 'http:\\\\www.google.com' here url is argument") (note the additional quotes, and double-backslash). But again, this feels very contrived since URIs don't contain backslashes!
|
0

It seems to me that if there's no consistent pattern to your command syntax, then any regex based approach will inevitably fail. It seems better instead to solve this problem the way a human would, i.e. with some knowledge of context.

In a *nix terminal, you can use the compgen command to list available commands. This Ruby script invokes that command to print the first 5 options from that list:

list = `cd ~ && compgen -c`
list_arr = list.split("\n")
list_arr[0,6].each{|x| puts x }

(The cd in the first line seems to be needed because of the context in which my Ruby is running with rvm.) For Windows, you may find this thread a useful starting point.

I'd match against the elements of this list to identify my commands, and take it from there.

Comments

0

Tom Lord's answer is far better than this one.


You probably want to look at OptionParser or GetOptLong if you need parsing of command line arguments provided to a ruby program.


If you are interested in parsing some strings that may or may not be commands with arguments, here's a quick-and-dirty:

I'd use scan instead of split with the following regex: /(".*"|[\w\:\:\.\-\\]+)/.

Best results come from: 'some string'.scan(/(".*"|[\w\:\:\.\-\\]+)/).flatten:

["ping", "http:\\www.google.com"]
["abc-abc", "-V"]
["abc-abc", "-L", "c:\\folder\\", "name\\test.log"]
# Technically, this is wrong, but so is the non-escaped whitespace.
["\"C:\\Program Files\\example\\program.exe\"", "-arg1", "-arg2"]
["\"C:\\Program Files\\example\\program.exe\""]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.