2015-12-06 21 views
7

Sto cercando un pacchetto che avrebbe preso una stringa come -v --format "some example" -i test e analizzare in una fetta di stringhe, la manipolazione citazioni, spazi, ecc correttamente:analizzare una stringa della riga di comando in bandiere e gli argomenti in Golang

-v 
--format 
some example 
-i 
test 

Ho controllato il pacchetto integrato flag e altri pacchetti di gestione flag su Github ma nessuno di essi sembra gestire questo caso particolare di analisi di una stringa non elaborata in token. Prima di provare a farlo da solo, preferirei cercare un pacchetto perché sono sicuro che ci sono molti casi speciali da gestire.

Qualche suggerimento?

+0

Questa è una miscela di ciò che la shell fa (il raggruppamento stringa tra virgolette) e il particolare comportamento degli strumenti opzione di analisi gnu (args intervallati e bandiere, e diverso tempo/formato bandiera corta). Non sono a conoscenza di nessuno che combini questi in un pacchetto. – JimB

+0

Un hack rapido (se si è flessibili di cambiare il modo in cui si fornisce l'input) sarebbe (si veda 'la documentazione del pacchetto flag'): \t \t set: = & flag.FlagSet {} \t \t v: = set .Bool ("v", false, "") \t formato: = set.String ("format", "", "") \t i: = set.String ("i", "", "") \t \t set.Parse ([] stringa { '-v',' --format = "qualche esempio" ',' -i = test'}) \t per k, v: = raggio set.Args() { \t \t log.Println (k, v) \t} \t \t log.Printf ("v =% v format =% vi =% v", * v, formato *, * i) –

+0

io non sono sicuro se Capisco. Stai pensando di fare qualcosa del tipo: 'cmd -v --format" qualche esempio "-i test'? Se è così, puoi semplicemente prendere tutti gli argomenti da 'os.Args'. – 425nesp

risposta

1

Per informazioni, questa è la funzione che ho finito per creare.

Dividi un comando nei suoi argomenti. Ad esempio, cat -v "some file.txt", restituirà ["cat", "-v", "some file.txt"].

Inoltre gestisce correttamente i caratteri di escape, in particolare gli spazi. Così cat -v some\ file.txt saranno anche correttamente essere diviso in ["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 
} 
Problemi correlati