복붙노트

[SCALA] 구문 분석 명령 줄 매개 변수에 가장 좋은 방법은? [닫은]

SCALA

구문 분석 명령 줄 매개 변수에 가장 좋은 방법은? [닫은]

스칼라 명령 줄 매개 변수를 구문 분석하는 가장 좋은 방법은 무엇입니까? 나는 개인적으로 외부 항아리가 필요하지 않습니다 뭔가 경량을 선호합니다.

관련 :

해결법

  1. ==============================

    1.대부분의 경우 당신은 외부 파서 필요하지 않습니다. 스칼라의 패턴 매칭은 기능적인 스타일의 인수를 소모 할 수 있습니다. 예를 들면 :

    대부분의 경우 당신은 외부 파서 필요하지 않습니다. 스칼라의 패턴 매칭은 기능적인 스타일의 인수를 소모 할 수 있습니다. 예를 들면 :

    object MmlAlnApp {
      val usage = """
        Usage: mmlaln [--min-size num] [--max-size num] filename
      """
      def main(args: Array[String]) {
        if (args.length == 0) println(usage)
        val arglist = args.toList
        type OptionMap = Map[Symbol, Any]
    
        def nextOption(map : OptionMap, list: List[String]) : OptionMap = {
          def isSwitch(s : String) = (s(0) == '-')
          list match {
            case Nil => map
            case "--max-size" :: value :: tail =>
                                   nextOption(map ++ Map('maxsize -> value.toInt), tail)
            case "--min-size" :: value :: tail =>
                                   nextOption(map ++ Map('minsize -> value.toInt), tail)
            case string :: opt2 :: tail if isSwitch(opt2) => 
                                   nextOption(map ++ Map('infile -> string), list.tail)
            case string :: Nil =>  nextOption(map ++ Map('infile -> string), list.tail)
            case option :: tail => println("Unknown option "+option) 
                                   exit(1) 
          }
        }
        val options = nextOption(Map(),arglist)
        println(options)
      }
    }
    

    예를 들어, 출력 할 것이다 :

    Map('infile -> test/data/paml-aln1.phy, 'maxsize -> 4, 'minsize -> 2)
    

    이 버전은 하나의 INFILE을합니다. 쉬운 (목록을 사용하여)에 향상시킬 수 있습니다.

    더 두를보다 -이 방법은 여러 명령 행 인수의 연결을 허용하는 것도주의!

  2. ==============================

    2.

    val parser = new scopt.OptionParser[Config]("scopt") {
      head("scopt", "3.x")
    
      opt[Int]('f', "foo") action { (x, c) =>
        c.copy(foo = x) } text("foo is an integer property")
    
      opt[File]('o', "out") required() valueName("<file>") action { (x, c) =>
        c.copy(out = x) } text("out is a required file property")
    
      opt[(String, Int)]("max") action { case ((k, v), c) =>
        c.copy(libName = k, maxCount = v) } validate { x =>
        if (x._2 > 0) success
        else failure("Value <max> must be >0") 
      } keyValueName("<libname>", "<max>") text("maximum count for <libname>")
    
      opt[Unit]("verbose") action { (_, c) =>
        c.copy(verbose = true) } text("verbose is a flag")
    
      note("some notes.\n")
    
      help("help") text("prints this usage text")
    
      arg[File]("<file>...") unbounded() optional() action { (x, c) =>
        c.copy(files = c.files :+ x) } text("optional unbounded args")
    
      cmd("update") action { (_, c) =>
        c.copy(mode = "update") } text("update is a command.") children(
        opt[Unit]("not-keepalive") abbr("nk") action { (_, c) =>
          c.copy(keepalive = false) } text("disable keepalive"),
        opt[Boolean]("xyz") action { (x, c) =>
          c.copy(xyz = x) } text("xyz is a boolean property")
      )
    }
    // parser.parse returns Option[C]
    parser.parse(args, Config()) map { config =>
      // do stuff
    } getOrElse {
      // arguments are bad, usage message will have been displayed
    }
    

    위는 다음 사용 텍스트를 생성합니다 :

    scopt 3.x
    Usage: scopt [update] [options] [<file>...]
    
      -f <value> | --foo <value>
            foo is an integer property
      -o <file> | --out <file>
            out is a required file property
      --max:<libname>=<max>
            maximum count for <libname>
      --verbose
            verbose is a flag
    some notes.
    
      --help
            prints this usage text
      <file>...
            optional unbounded args
    
    Command: update
    update is a command.
    
      -nk | --not-keepalive
            disable keepalive    
      --xyz <value>
            xyz is a boolean property
    

    이것은 내가 현재 사용하는 것입니다. 너무 많은 수하물없이 청소 사용. (면책 조항 : 지금이 프로젝트를 유지)

  3. ==============================

    3.나는 질문이 몇 시간 전에 질문을 받았다 실현,하지만 난 (나처럼) 주변에 인터넷 검색을하는 사람들을 도와 줄 알았는데,이 페이지를했다.

    나는 질문이 몇 시간 전에 질문을 받았다 실현,하지만 난 (나처럼) 주변에 인터넷 검색을하는 사람들을 도와 줄 알았는데,이 페이지를했다.

    가리비는 매우뿐만 아니라 유망 보인다.

    기능 (링크 GitHub의 페이지에서 인용) :

    그리고 (또한 Github의 페이지와는) 몇 가지 예제 코드 :

    import org.rogach.scallop._;
    
    object Conf extends ScallopConf(List("-c","3","-E","fruit=apple","7.2")) {
      // all options that are applicable to builder (like description, default, etc) 
      // are applicable here as well
      val count:ScallopOption[Int] = opt[Int]("count", descr = "count the trees", required = true)
                    .map(1+) // also here work all standard Option methods -
                             // evaluation is deferred to after option construction
      val properties = props[String]('E')
      // types (:ScallopOption[Double]) can be omitted, here just for clarity
      val size:ScallopOption[Double] = trailArg[Double](required = false)
    }
    
    
    // that's it. Completely type-safe and convenient.
    Conf.count() should equal (4)
    Conf.properties("fruit") should equal (Some("apple"))
    Conf.size.get should equal (Some(7.2))
    // passing into other functions
    def someInternalFunc(conf:Conf.type) {
      conf.count() should equal (4)
    }
    someInternalFunc(Conf)
    
  4. ==============================

    4.나는 비교적 간단한 구성에 대한 인수를 통해 슬라이딩 좋아합니다.

    나는 비교적 간단한 구성에 대한 인수를 통해 슬라이딩 좋아합니다.

    var name = ""
    var port = 0
    var ip = ""
    args.sliding(2, 2).toList.collect {
      case Array("--ip", argIP: String) => ip = argIP
      case Array("--port", argPort: String) => port = argPort.toInt
      case Array("--name", argName: String) => name = argName
    }
    
  5. ==============================

    5.여기 너무 내입니다! (늦게 게임 생각에 조금)

    여기 너무 내입니다! (늦게 게임 생각에 조금)

    https://github.com/backuity/clist

    반대로 것은 완전히 변경 가능한 scopt ...하지만 대기! 그것은 우리에게 꽤 좋은 구문을 제공합니다 :

    class Cat extends Command(description = "concatenate files and print on the standard output") {
    
      // type-safety: members are typed! so showAll is a Boolean
      var showAll        = opt[Boolean](abbrev = "A", description = "equivalent to -vET")
      var numberNonblank = opt[Boolean](abbrev = "b", description = "number nonempty output lines, overrides -n")
    
      // files is a Seq[File]
      var files          = args[Seq[File]](description = "files to concat")
    }
    

    그리고 간단한 방법은 그것을 실행합니다 :

    Cli.parse(args).withCommand(new Cat) { case cat =>
        println(cat.files)
    }
    

    당신은 더 과정을 많이 할 (다중 명령, 많은 구성 옵션, ...) 및 종속성이 없습니다 수 있습니다.

    나는 독특한 기능 (자주 다중 명령에 대한 무시) 기본 사용의 종류 마무리합니다 :

  6. ==============================

    6.이것은 주로 동일한 주제의 자바 질문에 대한 내 대답의 뻔뻔한 클론입니다. 그것은 JewelCLI가 자동 인수 이름을 얻을 자바 빈즈 스타일의 방법을 필요로하지 않는다는 점에서 스칼라하기 쉬운 것으로 나타났다.

    이것은 주로 동일한 주제의 자바 질문에 대한 내 대답의 뻔뻔한 클론입니다. 그것은 JewelCLI가 자동 인수 이름을 얻을 자바 빈즈 스타일의 방법을 필요로하지 않는다는 점에서 스칼라하기 쉬운 것으로 나타났다.

    JewelCLI 명령 줄 구문 분석하는 수익률 깨끗한 코드에 대한 스칼라 친화적 인 자바 라이브러리입니다. 그것은 동적 명령 줄 매개 변수의 형태 보증 된 API를 구축 주석과 프록시 인터페이스 구성된을 사용합니다.

    Person.scala 인터페이스 예 매개 변수 :

    import uk.co.flamingpenguin.jewel.cli.Option
    
    trait Person {
      @Option def name: String
      @Option def times: Int
    }
    

    Hello.scala 인터페이스 매개 변수의 사용 예 :

    import uk.co.flamingpenguin.jewel.cli.CliFactory.parseArguments
    import uk.co.flamingpenguin.jewel.cli.ArgumentValidationException
    
    object Hello {
      def main(args: Array[String]) {
        try {
          val person = parseArguments(classOf[Person], args:_*)
          for (i <- 1 to (person times))
            println("Hello " + (person name))
        } catch {
          case e: ArgumentValidationException => println(e getMessage)
        }
      }
    }
    

    하나의 디렉토리에 위의 해당 디렉토리에 JewelCLI 0.6 JAR를 다운로드뿐만 아니라 파일의 복사본 저장.

    컴파일 및 리눅스 / 맥 OS X / 등의 배쉬 예제를 실행 :

    scalac -cp jewelcli-0.6.jar:. Person.scala Hello.scala
    scala -cp jewelcli-0.6.jar:. Hello --name="John Doe" --times=3
    

    컴파일하고 Windows 명령 프롬프트에서 예제를 실행 :

    scalac -cp jewelcli-0.6.jar;. Person.scala Hello.scala
    scala -cp jewelcli-0.6.jar;. Hello --name="John Doe" --times=3
    

    예제를 실행하면 다음과 같은 출력을 생성한다 :

    Hello John Doe
    Hello John Doe
    Hello John Doe
    
  7. ==============================

    7.어떻게 외부 의존성없이 매개 변수를 구문 분석합니다. 좋은 질문! 당신은 picocli에 관심이있을 수 있습니다.

    어떻게 외부 의존성없이 매개 변수를 구문 분석합니다. 좋은 질문! 당신은 picocli에 관심이있을 수 있습니다.

    Picocli 특별히 질문에 질문 한 문제를 해결하기 위해 설계되었습니다 당신은 소스 형태로 포함시킬 수 있도록 그것은 하나의 파일에 프레임 워크를 구문 분석 명령 줄입니다. 이를 통해 사용자는 외부 종속성으로 picocli없이 picocli 기반 응용 프로그램을 실행할 수 있습니다.

    당신은 약간의 코드를 작성할 수 있도록이 필드를 주석으로 작동합니다. 빠른 요약 :

    사용법 도움말 메시지는 (프로그래밍없이) 주석과 사용자 정의하기 쉽습니다. 예를 들면 :

    (출처)

    나는 종류의 사용의 도움말 메시지를 가능한 무엇인지 보여 또 하나 개의 스크린 샷을 추가 저항 할 수 없었다. 사용에 도움이 응용 프로그램의 얼굴, 그래서 창조적 인 재미를!

    면책 조항 : 나는 picocli를 만들었습니다. 의견이나 질문은 매우 환영합니다. 그것은 자바로 작성하지만, 거기에 스칼라를 사용하는 모든 문제는 내가 그것을 해결하기 위해 노력 할게요 경우 알려 주시기있다.

  8. ==============================

    8.나는 스칼라 - optparse의-실용적 스칼라에서 가장 기능적인 명령 줄 파서 라이브러리라고 생각합니다.

    나는 스칼라 - optparse의-실용적 스칼라에서 가장 기능적인 명령 줄 파서 라이브러리라고 생각합니다.

    https://github.com/bmjames/scala-optparse-applicative

  9. ==============================

    9.간단한이, 사양이 더 읽기 (주석 덕분에)입니다 멋지게 출력 포맷 생산하고 있기 때문에 나는 args4j처럼 자바 세계에서 I를 생각합니다.

    간단한이, 사양이 더 읽기 (주석 덕분에)입니다 멋지게 출력 포맷 생산하고 있기 때문에 나는 args4j처럼 자바 세계에서 I를 생각합니다.

    여기 내 예를 조각입니다 :

    import org.kohsuke.args4j.{CmdLineException, CmdLineParser, Option}
    
    object CliArgs {
    
      @Option(name = "-list", required = true,
        usage = "List of Nutch Segment(s) Part(s)")
      var pathsList: String = null
    
      @Option(name = "-workdir", required = true,
        usage = "Work directory.")
      var workDir: String = null
    
      @Option(name = "-master",
        usage = "Spark master url")
      var masterUrl: String = "local[2]"
    
    }
    
    //var args = "-listt in.txt -workdir out-2".split(" ")
    val parser = new CmdLineParser(CliArgs)
    try {
      parser.parseArgument(args.toList.asJava)
    } catch {
      case e: CmdLineException =>
        print(s"Error:${e.getMessage}\n Usage:\n")
        parser.printUsage(System.out)
        System.exit(1)
    }
    println("workDir  :" + CliArgs.workDir)
    println("listFile :" + CliArgs.pathsList)
    println("master   :" + CliArgs.masterUrl)
    
    Error:Option "-list" is required
     Usage:
     -list VAL    : List of Nutch Segment(s) Part(s)
     -master VAL  : Spark master url (default: local[2])
     -workdir VAL : Work directory.
    
  10. ==============================

    10.또한 JCommander있다 (면책 조항 : 나는 그것을 만든) :

    또한 JCommander있다 (면책 조항 : 나는 그것을 만든) :

    object Main {
      object Args {
        @Parameter(
          names = Array("-f", "--file"),
          description = "File to load. Can be specified multiple times.")
        var file: java.util.List[String] = null
      }
    
      def main(args: Array[String]): Unit = {
        new JCommander(Args, args.toArray: _*)
        for (filename <- Args.file) {
          val f = new File(filename)
          printf("file: %s\n", f.getName)
        }
      }
    }
    
  11. ==============================

    11.나는 joslinm의 슬라이드 () 방식 만이 아닌 가변 바르 좋아) 그래서 여기에 그 접근 방식 불변 방법 :

    나는 joslinm의 슬라이드 () 방식 만이 아닌 가변 바르 좋아) 그래서 여기에 그 접근 방식 불변 방법 :

    case class AppArgs(
                  seed1: String,
                  seed2: String,
                  ip: String,
                  port: Int
                  )
    object AppArgs {
      def empty = new AppArgs("", "", "", 0)
    }
    
    val args = Array[String](
      "--seed1", "akka.tcp://seed1",
      "--seed2", "akka.tcp://seed2",
      "--nodeip", "192.167.1.1",
      "--nodeport", "2551"
    )
    
    val argsInstance = args.sliding(2, 1).toList.foldLeft(AppArgs.empty) { case (accumArgs, currArgs) => currArgs match {
        case Array("--seed1", seed1) => accumArgs.copy(seed1 = seed1)
        case Array("--seed2", seed2) => accumArgs.copy(seed2 = seed2)
        case Array("--nodeip", ip) => accumArgs.copy(ip = ip)
        case Array("--nodeport", port) => accumArgs.copy(port = port.toInt)
        case unknownArg => accumArgs // Do whatever you want for this case
      }
    }
    
  12. ==============================

    12.난 그냥 scalac의 scala.tools.cmd 패키지의 광범위한 명령 줄 구문 분석 라이브러리를 발견했습니다.

    난 그냥 scalac의 scala.tools.cmd 패키지의 광범위한 명령 줄 구문 분석 라이브러리를 발견했습니다.

    http://www.assembla.com/code/scala-eclipse-toolchain/git/nodes/src/compiler/scala/tools/cmd?rev=f59940622e32384b1e08939effd24e924a8ba8db 참조

  13. ==============================

    13.나는 시도했습니다 일반화 @ pjotrp의 솔루션이 필요 위치 키 기호 플래그의지도 목록에 복용하여 -> 키 기호 및 기본 옵션 :

    나는 시도했습니다 일반화 @ pjotrp의 솔루션이 필요 위치 키 기호 플래그의지도 목록에 복용하여 -> 키 기호 및 기본 옵션 :

    def parseOptions(args: List[String], required: List[Symbol], optional: Map[String, Symbol], options: Map[Symbol, String]): Map[Symbol, String] = {
      args match {
        // Empty list
        case Nil => options
    
        // Keyword arguments
        case key :: value :: tail if optional.get(key) != None =>
          parseOptions(tail, required, optional, options ++ Map(optional(key) -> value))
    
        // Positional arguments
        case value :: tail if required != Nil =>
          parseOptions(tail, required.tail, optional, options ++ Map(required.head -> value))
    
        // Exit if an unknown argument is received
        case _ =>
          printf("unknown argument(s): %s\n", args.mkString(", "))
          sys.exit(1)
      }
    }
    
    def main(sysargs Array[String]) {
      // Required positional arguments by key in options
      val required = List('arg1, 'arg2)
    
      // Optional arguments by flag which map to a key in options
      val optional = Map("--flag1" -> 'flag1, "--flag2" -> 'flag2)
    
      // Default options that are passed in
      var defaultOptions = Map()
    
      // Parse options based on the command line args
      val options = parseOptions(sysargs.toList, required, optional, defaultOptions)
    }
    
  14. ==============================

    14.나는 (dave4420에서) 상단의 대답에 내 접근 방식을 기반으로하며 좀 더 범용하여 그것을 개선하기 위해 노력했다.

    나는 (dave4420에서) 상단의 대답에 내 접근 방식을 기반으로하며 좀 더 범용하여 그것을 개선하기 위해 노력했다.

    그것은 모든 명령 줄 매개 변수의지도 [문자열, 문자열] 반환 당신은 당신이 원하는 특정 매개 변수 (예를 들어, 사용 .contains)이를 조회하거나 (toInt를 사용하여 예) 당신이 원하는 유형으로 값을 변환 할 수 있습니다.

    def argsToOptionMap(args:Array[String]):Map[String,String]= {
      def nextOption(
          argList:List[String], 
          map:Map[String, String]
        ) : Map[String, String] = {
        val pattern       = "--(\\w+)".r // Selects Arg from --Arg
        val patternSwitch = "-(\\w+)".r  // Selects Arg from -Arg
        argList match {
          case Nil => map
          case pattern(opt)       :: value  :: tail => nextOption( tail, map ++ Map(opt->value) )
          case patternSwitch(opt) :: tail => nextOption( tail, map ++ Map(opt->null) )
          case string             :: Nil  => map ++ Map(string->null)
          case option             :: tail => {
            println("Unknown option:"+option) 
            sys.exit(1)
          }
        }
      }
      nextOption(args.toList,Map())
    }
    

    예:

    val args=Array("--testing1","testing1","-a","-b","--c","d","test2")
    argsToOptionMap( args  )
    

    제공합니다 :

    res0: Map[String,String] = Map(testing1 -> testing1, a -> null, b -> null, c -> d, test2 -> null)
    
  15. ==============================

    15.다른 라이브러리 : 스카프

    다른 라이브러리 : 스카프

  16. ==============================

    16.여기에 사용하기 쉬운 스칼라 명령 줄 파서입니다. 자동으로 도움말 텍스트를 포맷하고, 원하는 유형 스위치 인수를 변환합니다. 두 짧은 POSIX, 긴 GNU 스타일의 스위치가 지원됩니다. 지원이 필요한 인수, 선택적 인수, 여러 값을 인수로 전환됩니다. 당신은 특정 스위치에 대해 사용할 수있는 값의 유한 목록을 지정할 수 있습니다. 긴 스위치 이름은 편의를 위해 명령 줄에서 생략 할 수있다. 루비 표준 라이브러리의 옵션을 파서 유사합니다.

    여기에 사용하기 쉬운 스칼라 명령 줄 파서입니다. 자동으로 도움말 텍스트를 포맷하고, 원하는 유형 스위치 인수를 변환합니다. 두 짧은 POSIX, 긴 GNU 스타일의 스위치가 지원됩니다. 지원이 필요한 인수, 선택적 인수, 여러 값을 인수로 전환됩니다. 당신은 특정 스위치에 대해 사용할 수있는 값의 유한 목록을 지정할 수 있습니다. 긴 스위치 이름은 편의를 위해 명령 줄에서 생략 할 수있다. 루비 표준 라이브러리의 옵션을 파서 유사합니다.

  17. ==============================

    17.나는 옵션을 파서 같은 루비를 좋아 한 적이있다. 자신의 스크립트에 대한 적절한 매뉴얼 페이지를 쓸 긴 옵션 때문에 파서의 적절한 방식으로 구성되지 페이지와 끝까지 결코 그들을 사용하는 대부분의 개발자.

    나는 옵션을 파서 같은 루비를 좋아 한 적이있다. 자신의 스크립트에 대한 적절한 매뉴얼 페이지를 쓸 긴 옵션 때문에 파서의 적절한 방식으로 구성되지 페이지와 끝까지 결코 그들을 사용하는 대부분의 개발자.

    난 항상 펄의 것은, Getopt :: 긴 함께 일을하는 펄의 방법을 선호했다.

    나는 그것의 스칼라 구현에 노력하고있다. 초기 API는 다음과 같은 :

    def print_version() = () => println("version is 0.2")
    
    def main(args: Array[String]) {
      val (options, remaining) = OptionParser.getOptions(args,
        Map(
          "-f|--flag"       -> 'flag,
          "-s|--string=s"   -> 'string,
          "-i|--int=i"      -> 'int,
          "-f|--float=f"    -> 'double,
          "-p|-procedure=p" -> { () => println("higher order function" }
          "-h=p"            -> { () => print_synopsis() }
          "--help|--man=p"  -> { () => launch_manpage() },
          "--version=p"     -> print_version,
        ))
    

    따라서이 같은 스크립트를 호출 :

    $ script hello -f --string=mystring -i 7 --float 3.14 --p --version world -- --nothing
    

    인쇄 할 것이다 :

    higher order function
    version is 0.2
    

    그리고 반환 :

    remaining = Array("hello", "world", "--nothing")
    
    options = Map('flag   -> true,
                  'string -> "mystring",
                  'int    -> 7,
                  'double -> 3.14)
    

    이 프로젝트는 GitHub의 스칼라 - getoptions에 호스팅됩니다.

  18. ==============================

    18.난 그냥 내 간단한 목록을 만들어

    난 그냥 내 간단한 목록을 만들어

    val args: Array[String] = "-silent -samples 100 -silent".split(" +").toArray
                                                  //> args  : Array[String] = Array(-silent, -samples, 100, -silent)
    object Opts extends Enumeration {
    
        class OptVal extends Val {
            override def toString = "-" + super.toString
        }
    
        val nopar, silent = new OptVal() { // boolean options
            def apply(): Boolean = args.contains(toString)
        }
    
        val samples, maxgen = new OptVal() { // integer options
            def apply(default: Int) = { val i = args.indexOf(toString) ;  if (i == -1) default else args(i+1).toInt}
            def apply(): Int = apply(-1)
        }
    }
    
    Opts.nopar()                              //> res0: Boolean = false
    Opts.silent()                             //> res1: Boolean = true
    Opts.samples()                            //> res2: Int = 100
    Opts.maxgen()                             //> res3: Int = -1
    

    그것은 스칼라 프로그램으로, 한 번만 자유 (당신이 훨씬 가치 있음을, 다른 라이브러리에 의존 즉)과 중복 (건조 원리, 당신은 옵션의 이름을 입력 할을 제거 : 그 솔루션을 분산시킬 수 두 가지 주요 결함을 가지고 이해 명령 줄 텍스트로 입력 변수를 제거 두 번째).

  19. ==============================

    19.나는 http://docopt.org/를 사용하는 것이 좋습니다 것입니다. 이 스칼라 포트입니다하지만 자바 구현 https://github.com/docopt/docopt.java은 잘 작동하고 더 나은 유지 될 것으로 보인다. 다음은 그 예이다 :

    나는 http://docopt.org/를 사용하는 것이 좋습니다 것입니다. 이 스칼라 포트입니다하지만 자바 구현 https://github.com/docopt/docopt.java은 잘 작동하고 더 나은 유지 될 것으로 보인다. 다음은 그 예이다 :

    import org.docopt.Docopt
    
    import scala.collection.JavaConversions._
    import scala.collection.JavaConverters._
    
    val doc =
    """
    Usage: my_program [options] <input>
    
    Options:
     --sorted   fancy sorting
    """.stripMargin.trim
    
    //def args = "--sorted test.dat".split(" ").toList
    var results = new Docopt(doc).
      parse(args()).
      map {case(key, value)=>key ->value.toString}
    
    val inputFile = new File(results("<input>"))
    val sorted = results("--sorted").toBoolean
    
  20. ==============================

    20.여기 토론에서 수집이 코드의 깨끗한 모습 ... 같은 I : http://www.scala-lang.org/old/node/4380

    여기 토론에서 수집이 코드의 깨끗한 모습 ... 같은 I : http://www.scala-lang.org/old/node/4380

    object ArgParser {
      val usage = """
    Usage: parser [-v] [-f file] [-s sopt] ...
    Where: -v   Run verbosely
           -f F Set input file to F
           -s S Set Show option to S
    """
    
      var filename: String = ""
      var showme: String = ""
      var debug: Boolean = false
      val unknown = "(^-[^\\s])".r
    
      val pf: PartialFunction[List[String], List[String]] = {
        case "-v" :: tail => debug = true; tail
        case "-f" :: (arg: String) :: tail => filename = arg; tail
        case "-s" :: (arg: String) :: tail => showme = arg; tail
        case unknown(bad) :: tail => die("unknown argument " + bad + "\n" + usage)
      }
    
      def main(args: Array[String]) {
        // if there are required args:
        if (args.length == 0) die()
        val arglist = args.toList
        val remainingopts = parseArgs(arglist,pf)
    
        println("debug=" + debug)
        println("showme=" + showme)
        println("filename=" + filename)
        println("remainingopts=" + remainingopts)
      }
    
      def parseArgs(args: List[String], pf: PartialFunction[List[String], List[String]]): List[String] = args match {
        case Nil => Nil
        case _ => if (pf isDefinedAt args) parseArgs(pf(args),pf) else args.head :: parseArgs(args.tail,pf)
      }
    
      def die(msg: String = usage) = {
        println(msg)
        sys.exit(1)
      }
    
    }
    
  21. ==============================

    21.모든 사람이 게시 된 내가이 사용자에 대해 쓰기로 쉽게 무언가를 원 원인, 자신의 솔루션은 여기 내 꺼야 : https://gist.github.com/gwenzek/78355526e476e08bb34d

    모든 사람이 게시 된 내가이 사용자에 대해 쓰기로 쉽게 무언가를 원 원인, 자신의 솔루션은 여기 내 꺼야 : https://gist.github.com/gwenzek/78355526e476e08bb34d

    요점은 코드 파일 플러스 테스트 파일을 여기에 복사 간단한 예제를 포함 :

    import ***.ArgsOps._
    
    
    object Example {
        val parser = ArgsOpsParser("--someInt|-i" -> 4, "--someFlag|-f", "--someWord" -> "hello")
    
        def main(args: Array[String]){
            val argsOps = parser <<| args
            val someInt : Int = argsOps("--someInt")
            val someFlag : Boolean = argsOps("--someFlag")
            val someWord : String = argsOps("--someWord")
            val otherArgs = argsOps.args
    
            foo(someWord, someInt, someFlag)
        }
    }
    

    일부 경계에있을 변수를 강제로 멋진 옵션이 아니라, 내가 파서 그렇게 할 수있는 가장 좋은 곳이라고 생각하지 않습니다 원인이된다.

    참고 : 특정 변수에 원하는 수만큼 별칭을 가질 수 있습니다.

  22. ==============================

    22.나는에 쌓아거야. 나는 코드의 간단한 라인이를 해결했다. 내 명령 줄 인수는 다음과 같습니다 :

    나는에 쌓아거야. 나는 코드의 간단한 라인이를 해결했다. 내 명령 줄 인수는 다음과 같습니다 :

    input--hdfs:/path/to/myData/part-00199.avro output--hdfs:/path/toWrite/Data fileFormat--avro option1--5
    

    이 (어느 앱 또는 주요 방법)에서 스칼라의 기본 명령 라인 기능을 통해 배열을 작성

    Array("input--hdfs:/path/to/myData/part-00199.avro", "output--hdfs:/path/toWrite/Data","fileFormat--avro","option1--5")
    

    나는 그 기본 args 배열을 구문 분석이 줄을 사용할 수 있습니다 :

    val nArgs = args.map(x=>x.split("--")).map(y=>(y(0),y(1))).toMap
    

    어떤 명령 행 값과 관련된 이름을 가진지도를 만듭니다

    Map(input -> hdfs:/path/to/myData/part-00199.avro, output -> hdfs:/path/toWrite/Data, fileFormat -> avro, option1 -> 5)
    

    그때 나는 내 코드에서 명명 된 매개 변수의 값을 액세스 할 수 있으며 명령 행에 나타나는 순서는 더 이상 관련이있다. 나는 이것이 매우 간단하고 모든 고급 기능은 위에서 언급되어 있지 않지만 대부분의 경우 충분한 것 같다, 단 한 줄의 코드를 필요로하고, 외부 종속성을 포함하지 않습니다 알고 있습니다.

  23. ==============================

    23.여기서 내 1 라이너는

    여기서 내 1 라이너는

        def optArg(prefix: String) = args.drop(3).find { _.startsWith(prefix) }.map{_.replaceFirst(prefix, "")}
        def optSpecified(prefix: String) = optArg(prefix) != None
        def optInt(prefix: String, default: Int) = optArg(prefix).map(_.toInt).getOrElse(default)
    

    그것은 3 개 필수 인수를 떨어지고있는 옵션을 제공합니다. 정수는 공동 접두사로, 악명 -Xmx <크기> 자바 옵션과 같이 지정됩니다. 당신은 간단하게 바이너리와 정수를 분석 할 수

    val cacheEnabled = optSpecified("cacheOff")
    val memSize = optInt("-Xmx", 1000)
    

    수입 아무것도 필요가 없습니다.

  24. ==============================

    24.이것은 내가 요리 것입니다. 그것은지도와 목록의 튜플을 반환합니다. 목록 입력 파일 이름과 같이 입력합니다. 지도는 스위치 / 옵션이다.

    이것은 내가 요리 것입니다. 그것은지도와 목록의 튜플을 반환합니다. 목록 입력 파일 이름과 같이 입력합니다. 지도는 스위치 / 옵션이다.

    val args = "--sw1 1 input_1 --sw2 --sw3 2 input_2 --sw4".split(" ")
    val (options, inputs) = OptParser.parse(args)
    

    반환

    options: Map[Symbol,Any] = Map('sw1 -> 1, 'sw2 -> true, 'sw3 -> 2, 'sw4 -> true)
    inputs: List[Symbol] = List('input_1, 'input_2)
    

    스위치는 true로 설정됩니다, 또는 "--x 10"어떤 X가 "10"로 설정 될 X "--t"이 될 수 있습니다. 다른 모든 목록에 종료됩니다.

    object OptParser {
      val map: Map[Symbol, Any] = Map()
      val list: List[Symbol] = List()
    
      def parse(args: Array[String]): (Map[Symbol, Any], List[Symbol]) = _parse(map, list, args.toList)
    
      private [this] def _parse(map: Map[Symbol, Any], list: List[Symbol], args: List[String]): (Map[Symbol, Any], List[Symbol]) = {
        args match {
          case Nil => (map, list)
          case arg :: value :: tail if (arg.startsWith("--") && !value.startsWith("--")) => _parse(map ++ Map(Symbol(arg.substring(2)) -> value), list, tail)
          case arg :: tail if (arg.startsWith("--")) => _parse(map ++ Map(Symbol(arg.substring(2)) -> true), list, tail)
          case opt :: tail => _parse(map, list :+ Symbol(opt), tail)
        }
      }
    }
    
  25. ==============================

    25.freecli

    freecli

    package freecli
    package examples
    package command
    
    import java.io.File
    
    import freecli.core.all._
    import freecli.config.all._
    import freecli.command.all._
    
    object Git extends App {
    
      case class CommitConfig(all: Boolean, message: String)
      val commitCommand =
        cmd("commit") {
          takesG[CommitConfig] {
            O.help --"help" ::
            flag --"all" -'a' -~ des("Add changes from all known files") ::
            O.string -'m' -~ req -~ des("Commit message")
          } ::
          runs[CommitConfig] { config =>
            if (config.all) {
              println(s"Commited all ${config.message}!")
            } else {
              println(s"Commited ${config.message}!")
            }
          }
        }
    
      val rmCommand =
        cmd("rm") {
          takesG[File] {
            O.help --"help" ::
            file -~ des("File to remove from git")
          } ::
          runs[File] { f =>
            println(s"Removed file ${f.getAbsolutePath} from git")
          }
        }
    
      val remoteCommand =
       cmd("remote") {
         takes(O.help --"help") ::
         cmd("add") {
           takesT {
             O.help --"help" ::
             string -~ des("Remote name") ::
             string -~ des("Remote url")
           } ::
           runs[(String, String)] {
             case (s, u) => println(s"Remote $s $u added")
           }
         } ::
         cmd("rm") {
           takesG[String] {
             O.help --"help" ::
             string -~ des("Remote name")
           } ::
           runs[String] { s =>
             println(s"Remote $s removed")
           }
         }
       }
    
      val git =
        cmd("git", des("Version control system")) {
          takes(help --"help" :: version --"version" -~ value("v1.0")) ::
          commitCommand ::
          rmCommand ::
          remoteCommand
        }
    
      val res = runCommandOrFail(git)(args).run
    }
    

    이는 다음 사용을 생성합니다 :

    용법

  26. ==============================

    26.키 = 값 쌍을 구문 분석 가난한 사람의 빠른 - 및 - 더러운 한 줄 :

    키 = 값 쌍을 구문 분석 가난한 사람의 빠른 - 및 - 더러운 한 줄 :

    def main(args: Array[String]) {
        val cli = args.map(_.split("=") match { case Array(k, v) => k->v } ).toMap
        val saveAs = cli("saveAs")
        println(saveAs)
    }
    
  27. from https://stackoverflow.com/questions/2315912/best-way-to-parse-command-line-parameters by cc-by-sa and MIT license