parse go flags with more than one value

Viewed 2184

I've the following code and I need to get the values like val1 and val2 and arg1 and arg2 and print it, I've tried many ways, is it possible ?

package main

import (
    "flag"
    "fmt"
    "strings"
)

func main() {
    args := strings.Fields("-loc .env -names val1 val2 -tags arg1 arg2")



    FlagSet := flag.NewFlagSet("FlagSet", flag.ContinueOnError)
    loc := FlagSet.String("loc", "", "")
    name := FlagSet.String("names", "", "")
    tags := FlagSet.String("tags", "", "")
    

    FlagSet.Parse(args)

    fmt.Printf("location: %s \n", *loc)
    fmt.Printf("name: %s \n", *name)
    fmt.Printf("tags: %s \n", *tags)
}

https://play.golang.org/p/8aN5-0EZ2OT

2 Answers

What you want is not how flags are parsed by the stdlib flag package: https://golang.org/pkg/flag/#hdr-Command_line_flag_syntax. A flag can have a single argument.

The best you can do is -loc .env -names "val1 val2" -tags "arg1 arg2" or -loc .env -names val1,val2 -tags arg1,arg2. In the first case the double quotes turn the multiple words into a single command-line argument, and in the second using a comma instead of a space combines the arguments. In both cases you'll have to parse the result into individual arguments, perhaps using strings.Split.

Note that you use strings.Fields to break your test arguments into space-separated fields, but this ignores quotes, which differs from the behaviour of your command-line.

As shell use space(" ") as separator, it is not a good idea to use space as the separator. Use comma "," as the separator could solve this problem elegantly.

https://play.golang.org/p/xF2N_qnRlwe

package main

import (
    "flag"
    "fmt"
    "strings"
)

func main() {
    //NOT GOOD - multiple values (see value1 value2)
    args := strings.Fields(`-loc .env -names val1,val2 -tags arg1,arg2`)

    FlagSet := flag.NewFlagSet("FlagSet", flag.ContinueOnError)
    loc := FlagSet.String("loc", "", "")
    names := FlagSet.String("names", "", "")
    tags := FlagSet.String("tags", "", "")

    FlagSet.Parse(args)

    fmt.Printf("location: %s \n", *loc)
    fmt.Printf("names: %s \n", strings.Split(*names, ","))
    fmt.Printf("tags: %s \n", strings.Split(*tags, ","))
}

Related