Command Line Tool
iOSアプリしか開発しない人には縁がないかもしれませんが,Xcodeで新規プロジェクトを作る際,Command Line Toolのテンプレートを選択するとCUIベースのソフトウェアを作ることができます.普段からSwiftを使っていて,CSVの加工とかちょっとした文字列の加工処理などをしたいけれど,大きなGUIプロジェクトを立ち上げるほどでもないという状況にもってこいなので,どんどん使っていきましょう.今回はCommand Line ToolでCSVファイルを読み込むところまでを記述します.
プロジェクト立ち上げ
XcodeのFile
-> New
-> Project...
-> macOS
-> Command Line Tool
から立ち上げられます.野良の.swift
ファイルを作ってVS CodeとかAtomとか外部のエディタでガリゴリ書いても良いのですが,やはりXcodeの強力な補完の恩恵は惜しいですからね.
実装
今回はこちらのダミーCSVファイルを読み込むこととします.
一行目は各列の項目名になっています.
valueA,valueB,valueC
1,3.14,pi
2,2.718,e
3,1.414,square root 2
それではmain.swift
ファイルを編集します.
import Foundation
struct Dummy {
let a: Int
let b: Float
let c: String
init(_ a: Int, _ b: Float, c: String) {
self.a = a
self.b = b
self.c = c
}
var description: String {
return "a: \(self.a), b: \(self.b), c: \"\(self.c)\""
}
}
let input = FileHandle.standardInput
var data = [Dummy]()
func scan() -> String {
let text = String(data: input.availableData, encoding: String.Encoding.utf8) ?? ""
return text.trimmingCharacters(in: CharacterSet.newlines)
}
func main() {
let filePath = scan()
guard let file = try? String(contentsOfFile: filePath, encoding: String.Encoding.utf8) else { exit(0) }
var first: Bool = true
file.enumerateLines { (line, stop) in
if first {
first = false
} else {
let item = line.components(separatedBy: ",")
data.append(Dummy(Int(item[0])!, Float(item[1])!, c: item[2]))
}
}
data.forEach { (dummy) in
Swift.print(dummy.description)
}
}
main()
まず,CSVファイルに合わせてDummy
という構造体を用意しました.
scan()
メソッドは標準入力を受け付けて改行を入力すると文字列を返します.
\main()`メソッドではCSVファイルの中身をUTF-8で読み込んで一行ずつ処理を行い,Dummyのデータを配列に追加し,最終的に出力しています.
実行
XcodeでRunしてもいいのですがXcodeのdebugエリアへの標準入力は文字が不可視となることがあり不安定なので,Terminal.appでmain.swiftを実行します.
$ cd ~/Desktop/CommandLine/CommandLine/ <-- [main.swiftが入っているディレクトリのパス]
$ swift main.swift
./dummy.csv <-- [CSVファイルのパス]
a: 1, b: 3.14, c: "pi"
a: 2, b: 2.718, c: "e"
a: 3, b: 1.414, c: "square root 2"
$
CSVファイルをmain.swiftと同じディレクトリに入れておくと,ファイル指定が楽ですね.
ちなみに,コマンドライン引数をとりたい時はこちらの記事を参考にしてみてください.