LoginSignup
7
5

More than 5 years have passed since last update.

csvファイルをgroovyでJSONに変換する

Posted at

手元にあるcsvファイルをElasticsearchにbulkAPIで投入したかったので、JSONに変換するgroovyスクリプトを書きました。

意外にも新しい発見もあったのでメモ代わりに残しておきます。

inputファイル

見出し行がついたCSVファイル(UTF-8)を想定。

input.csv
event_date_time,name
2015/09/01 01:02:03,田中
2015/09/02 04:05:06,山田

ソース

Convert.groovy
import groovy.json.JsonBuilder
import groovy.json.StringEscapeUtils

new File("output.json").withWriter("UTF-8") { writer -> 
    new File("input.csv").eachLine("UTF-8", 0){ String line, int number ->
        if(number == 0) return

        def data = line.split(",")
        def json = new JsonBuilder()
        json (
            "index" : [
                    "_index": "index_name",
                    "_type" : "type_name",
                    "_id" : number
            ],
                "event_date_time" : data[0],
                "name" : data[1]
        )
        writer.write(StringEscapeUtils.unescapeJavaScript(json.toString()) + "\n")
    }
}

勉強になったこと(1) firstLineの意味

java.io.File#eachLine(String charset, int firstLine, Closure c)のfirstLineですが、2と指定すると1行目を無視して2行目から読み込んでくれるのかと思っていました。

そのため、以下のようなコードを書き、なんで全部出力されるんだろうと??な状態でした。

new File("input.csv").eachLine(2){ String line ->
   ・・・
}

よくよくドキュメントを読むと普通に書いてありました。
実はclosureに渡す行番号の初期値とのこと。

Parameters:
firstLine - the line number value used for the first line (default is 1, set to 0 to start counting from 0)
closure - a closure (arg 1 is line, optional arg 2 is line number)

ファイル操作ではeachWithIndexがないのかと思っていたら、その機能相当のものがeachLineでできたんですね。知らなかった。

勉強になったこと(2) JsonBuilderで日本語出力する

groovy.json.JsonBuilder#toString() では日本語はエスケープされた状態で出力されるようです。

エスケープされた文字を元に戻すためには、groovy.json.StringEscapeUtils#unescapeJavaScript(String str) を使ってやればいいようです


簡単なスクリプトですがやはり自分で手を動かすと理解も深まります。

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5