你如何在Swift中访问命令行参数?

时间:2014-06-04 05:23:49

标签: macos command-line-arguments swift

如何在Swift中访问命令行应用程序的命令行参数?

6 个答案:

答案 0 :(得分:284)

更新01/17/17:更新了Swift 3的示例。Process已重命名为CommandLine


2015年9月30日更新:更新了可在Swift 2中使用的示例。


实际上可以在没有基础 C_ARGVC_ARGC的情况下执行此操作。

Swift标准库包含一个结构CommandLine,它有一个名为String的{​​{1}}集合。所以你可以打开这样的参数:

arguments

答案 1 :(得分:54)

在Swift 3中使用CommandLine枚举而不是Process

所以:

let arguments = CommandLine.arguments

答案 2 :(得分:44)

使用顶级常量C_ARGCC_ARGV

for i in 1..C_ARGC {
    let index = Int(i);

    let arg = String.fromCString(C_ARGV[index])
    switch arg {
    case "this":
        println("this yo");

    case "that":
        println("that yo")

    default:
        println("dunno bro")
    }
}

请注意,我使用1..C_ARGC的范围,因为C_ARGV"数组的第一个元素"是应用程序的路径。

C_ARGV变量实际上不是一个数组,但可以像数组一样进行子脚本编写。

答案 3 :(得分:11)

任何想要使用旧版" getopt" (可在Swift中使用)可以使用它作为参考。我在C中创建了一个GNU示例的Swift端口,可以找到:

http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html

有完整的描述。它经过测试并且功能齐全。它也不需要基金会。

var aFlag   = 0
var bFlag   = 0
var cValue  = String()

let pattern = "abc:"
var buffer = Array(pattern.utf8).map { Int8($0) }

while  true {
    let option = Int(getopt(C_ARGC, C_ARGV, buffer))
    if option == -1 {
        break
    }
    switch "\(UnicodeScalar(option))"
    {
    case "a":
        aFlag = 1
        println("Option -a")
    case "b":
        bFlag = 1
        println("Option -b")
    case "c":
        cValue = String.fromCString(optarg)!
        println("Option -c \(cValue)")
    case "?":
        let charOption = "\(UnicodeScalar(Int(optopt)))"
        if charOption == "c" {
            println("Option '\(charOption)' requires an argument.")
        } else {
            println("Unknown option '\(charOption)'.")
        }
        exit(1)
    default:
        abort()
    }
}
println("aflag ='\(aFlag)', bflag = '\(bFlag)' cvalue = '\(cValue)'")

for index in optind..<C_ARGC {
    println("Non-option argument '\(String.fromCString(C_ARGV[Int(index)])!)'")
}

答案 4 :(得分:8)

Apple为此发布了Function<String, Map<String, Long>> function = f -> { Long count = listofComments.stream() .filter(e -> e.toLowerCase().contains(f.toLowerCase())).count(); Map<String, Long> map = new HashMap<>(); //creates map for every element. Is it right? map.put(f, count); return map; }; elements.stream().sorted().map(function).forEach(e-> System.out.print(e)); 库:

我们很高兴宣布ArgumentParser,这是一个新的开放源代码库,使它变得简单明了-甚至令人愉快! —在Swift中解析命令行参数。

https://swift.org/blog/argument-parser/


快速参数解析器

https://github.com/apple/swift-argument-parser

首先声明一个定义您需要从命令行收集的信息的类型。用ArgumentParser的属性包装器之一装饰每个存储的属性,并声明符合ArgumentParser

ParsableCommand库将解析命令行参数,实例化您的命令类型,然后执行您的自定义ArgumentParser方法或退出并显示一条有用的消息。

答案 5 :(得分:1)

您可以使用CommandLine.arguments数组创建一个参数解析器,并添加所需的任何逻辑。

您可以对其进行测试。创建文件arguments.swift

//Remember the first argument is the name of the executable
print("you passed \(CommandLine.arguments.count - 1) argument(s)")
print("And they are")
for argument in CommandLine.arguments {
    print(argument)
}

编译并运行它:

$ swiftc arguments.swift
$ ./arguments argument1 argument2 argument3

构建自己的参数解析器时遇到的问题是要考虑所有命令行参数约定。我建议使用现有的参数解析器。

您可以使用:

  • Vapor的控制台模块
  • Swift软件包管理器使用的TSCUtility参数解析器
  • Apple开源的Swift Argument Parser

我已经写了关于如何在所有三个工具上构建命令行工具的文章。您应该检查一下它们,然后确定哪种样式最适合您。

如果您对此感兴趣,请访问以下链接: