2015-12-06 52 views
7

Szukam pakietu, który wziąłby ciąg taki jak -v --format "some example" -i test i przetwarza go w plasterek strun, obsługi cytaty, spacje itp odpowiednio:Przetwarza liniowy ciąg poleceń do flagi i argumentów w Golang

-v 
--format 
some example 
-i 
test 

Sprawdziłem wbudowany pakiet flag, a także inne pakiety obsługi flag na Githubie, ale żaden z nich nie obsługuje tego konkretnego przypadku przetwarzania nieprzetworzonego łańcucha na tokeny. Zanim spróbuję zrobić to sam, wolę poszukać pakietu, ponieważ jestem pewien, że jest wiele specjalnych przypadków do obsłużenia.

Jakieś sugestie?

+0

jest mieszaniną tego, co robi powłoka (cytowany grupowanie string), a zwłaszcza zachowanie gnu narzędzi opcja dekodowaniu (usytuowane w odstępach args i flagi, a inna długa/krótki format flagi). Nie jestem świadomy, że ktokolwiek łączy je w pakiet. – JimB

+0

Szybkie Hack (jeśli są elastyczne, aby zmienić sposób dostarczania wejście) byłoby (zobacz 'dokumentację flag' innych pakietów): \t \t Set: = & flag.FlagSet {} \t \t v: = zbiór .Bool ("v", false, "") \t format: = ustawiony.String ("format", "", "") \t i: = set.String ("i", "", "") \t \t Zestaw.Parse ([] string {'-v',' --format = "przykład" ",' -i = test'}) \t dla k, v: = zakres set.Args() { \t \t log.Println (k, v) \t} \t \t log.Printf ("v =% v vi format =% =% v" * v * Format * i) –

+0

Nie jestem pewien, czy Rozumiem. Czy planujesz zrobić coś takiego: 'cmd -v --format" jakiś przykład "-i test"? Jeśli tak, możesz po prostu pobrać wszystkie argumenty z 'os.Args'. – 425nesp

Odpowiedz

1

Dla informacji, jest to funkcja, którą stworzyłem.

Dzieli polecenie na swoje argumenty. Na przykład: cat -v "some file.txt", zwróci ["cat", "-v", "some file.txt"].

To również poprawnie obsługuje znaki zbiegów, w szczególności spacje. Więc cat -v some\ file.txt będą również prawidłowo podzielić na ["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 
}