将命令行字符串解析为Golang中的标志和参数
I'm looking for a package that would take a string such as -v --format "some example" -i test
and parse it into a slice of strings, handling quotes, spaces, etc. properly:
-v
--format
some example
-i
test
For information, this is the function I've ended up creating.
It splits a command into its arguments. For example, cat -v "some file.txt"
, will return ["cat", "-v", "some file.txt"]
.
It also correctly handles escaped characters, spaces in particular. So cat -v some\ file.txt
will also correctly be split into ["cat", "-v", "some file.txt"]
func parseCommandLine(command string) ([]string, error) {
var args []string
state := "start"
current := ""
quote := """
escapeNext := true
for i := 0; i < len(command); i++ {
c := command[i]
if state == "quotes" {
if string(c) != quote {
current += string(c)
} else {
args = append(args, current)
current = ""
state = "start"
}
continue
}
if (escapeNext) {
current += string(c)
escapeNext = false
continue
}
if (c == '\\') {
escapeNext = true
continue
}
if c == '"' || c == '\'' {
state = "quotes"
quote = string(c)
continue
}
if state == "arg" {
if c == ' ' || c == '\t' {
args = append(args, current)
current = ""
state = "start"
} else {
current += string(c)
}
continue
}
if c != ' ' && c != '\t' {
state = "arg"
current += string(c)
}
}
if state == "quotes" {
return []string{}, errors.New(fmt.Sprintf("Unclosed quote in command line: %s", command))
}
if current != "" {
args = append(args, current)
}
return args, nil
}
If the args were passed to your program on the command line then the shell should handle this and os.Args
will be populated correctly. For example, in your case os.Args[1:]
will equal
[]string{"-v", "--format", "some example", "-i", "test"}
hedzr/cmdr might be good. it's a getopt-like command-line parser, light weight, fluent api or classical style.
本文由 创作,采用 知识共享署名4.0 国际许可协议进行许可。本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为: 2021/03/27 11:29