Last active
December 16, 2015 16:49
-
-
Save amake/5465701 to your computer and use it in GitHub Desktop.
A function for correctly parsing CLI commands with quotes and escape characters, on Windows, Linux, and OS X.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************************************************************** | |
Public Domain | |
To the extent possible under law, Aaron Madlon-Kay has waived all | |
copyright and related or neighboring rights to this work. | |
This work is published from: Japan | |
**************************************************************************/ | |
package org.amk; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class ParseCLI { | |
/** | |
* Parse a command line string into arguments, interpreting | |
* double and single quotes as Bash does. | |
* | |
* Use '\' to escape whitespace (outside of quotes only) | |
* and to escape double quotes (inside double quotes only). | |
* | |
* This is suitable for parsing arguments to be passed to | |
* {@link Runtime#exec(String[])}, on Windows, Linux, and | |
* OS X. | |
* | |
* @param cmd Command string | |
* @return Array of arguments | |
*/ | |
public static String[] parseCLICommand(String cmd) { | |
cmd = cmd.trim(); | |
if (cmd.length() == 0) return new String[] { "" }; | |
StringBuilder arg = new StringBuilder(); | |
List<String> result = new ArrayList<String>(); | |
final char noQuote = '\0'; | |
char currentQuote = noQuote; | |
for (int i = 0; i < cmd.length(); i++) { | |
char c = cmd.charAt(i); | |
if (c == currentQuote) { | |
currentQuote = noQuote; | |
} else if (c == '"' && currentQuote == noQuote) { | |
currentQuote = '"'; | |
} else if (c == '\'' && currentQuote == noQuote) { | |
currentQuote = '\''; | |
} else if (c == '\\' && i + 1 < cmd.length()) { | |
char next = cmd.charAt(i + 1); | |
if ((currentQuote == noQuote && Character.isWhitespace(next)) | |
|| (currentQuote == '"' && next == '"')) { | |
arg.append(next); | |
i++; | |
} else { | |
arg.append(c); | |
} | |
} else { | |
if (Character.isWhitespace(c) && currentQuote == noQuote) { | |
if (arg.length() > 0) { | |
result.add(arg.toString()); | |
arg = new StringBuilder(); | |
} else { | |
// Discard | |
} | |
} else { | |
arg.append(c); | |
} | |
} | |
} | |
// Catch last arg | |
if (arg.length() > 0) { | |
result.add(arg.toString()); | |
} | |
return result.toArray(new String[0]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment