patternjavaMinor
Splitting a command line into key/value pairs
Viewed 0 times
lineintosplittingvaluecommandpairskey
Problem
The code below will split environment variables from a command line (always appear at the end of the command line). Environment variables are represented by '-E key=value'. I've achieved this like so, but I'm wondering if there's a more elegant way
EDIT Just to clarify these aren't command line arguments for launching the program from the console, they are command line arguments for launching an external program. The details of which I haven't included.
public class TestSplit {
public static void main(String... args) {
String command = "-ps 4 -pe 5 -E opInstallDir=/home/paul -E opWD=/home/paul/remake -E opFam=fam -E opAppli=appli";
int startPosition = command.indexOf("-E") + 2;
String envVars = command.substring(startPosition);
for(String pair: envVars.split("-E")) {
String[] kv = pair.split("=");
System.out.println(kv[0] + " " +kv[1]);
}
}
}EDIT Just to clarify these aren't command line arguments for launching the program from the console, they are command line arguments for launching an external program. The details of which I haven't included.
Solution
Like @palacsint I will recommend an external library. Apache commons-cli is a decent choice. Another choice (my preference) is java gnu-getopt ... I like it because I am familiar with the notations and standards from previous work. It can be a little complicated the first time around otherwise.
On the other hand, I tend not to use an external library unless the code is already going to be relatively complicated....
But, back to your code.
Why do you have everything in a single String? Why is it not part of the
The first thing about command-line arguments is that they get complicated very fast. What if the argument was:
I have thrown in a few things there.
First up, on our one machine at work, we really do have the directory /opt/OSS-EVAL/ which we use to install/evaluate OSS software/libraries.
The above will break your parsing because it has the
Next up, is 'POSIX-style' commandline arguments can have quoted values, and also values with an
So, things I would recommend to you:
Locate the source of your command-line values. It will likely be available as an array, not a single string. Keep the data as an array!
Second, with the array, it is easier to look for stand-alone values that are
Finally, when you split the key/value on the
Which will preserve any of the
EDIT:
You have suggested in your edit that this is for sending data to an external command.
If you are using Java to initialize the external command, then please, please, please use the version of exec() that takes a command array, or use the ProcessBuilder which allows you to send all the command-line parameters as separate values in an array!!!
On the other hand, I tend not to use an external library unless the code is already going to be relatively complicated....
But, back to your code.
Why do you have everything in a single String? Why is it not part of the
String...args ?The first thing about command-line arguments is that they get complicated very fast. What if the argument was:
String command = "-ps 4 -pe 5 -E opInstallDir=/opt/OSS-EVAL/thiscode -E opWD=/home/paul/remake -E opFam=fam -E opAppli=appli -Edocs='My Documents' -Eparse=key=value";I have thrown in a few things there.
First up, on our one machine at work, we really do have the directory /opt/OSS-EVAL/ which we use to install/evaluate OSS software/libraries.
The above will break your parsing because it has the
-E embedded in the name.Next up, is 'POSIX-style' commandline arguments can have quoted values, and also values with an
= in the value.So, things I would recommend to you:
Locate the source of your command-line values. It will likely be available as an array, not a single string. Keep the data as an array!
Second, with the array, it is easier to look for stand-alone values that are
-E, or, if the input is -Ekey=value then you look for values that start with -E.Finally, when you split the key/value on the
=, limit the split to 2.String[] kv = pair.split("=", 2);Which will preserve any of the
= tokens inside the value part.EDIT:
You have suggested in your edit that this is for sending data to an external command.
If you are using Java to initialize the external command, then please, please, please use the version of exec() that takes a command array, or use the ProcessBuilder which allows you to send all the command-line parameters as separate values in an array!!!
Code Snippets
String command = "-ps 4 -pe 5 -E opInstallDir=/opt/OSS-EVAL/thiscode -E opWD=/home/paul/remake -E opFam=fam -E opAppli=appli -Edocs='My Documents' -Eparse=key=value";String[] kv = pair.split("=", 2);Context
StackExchange Code Review Q#43697, answer score: 4
Revisions (0)
No revisions yet.