[Groovy]マッチした都道府県名を行末に追加するPerlスクリプトをGroovyで実装

# 概要
[【Perl】マッチした都道府県名を行末に追加するスクリプト](http://chalow.net/2016-10-17-1.html) の内容が素敵だったので、Groovyでも実装してみました。  
なお、実装に辺り上記サイトのオプションや実行方法などは若干変更しています。  

# コードとデータ

```groovy:sample.groovy
def prefs = ['愛知県', '青森県', '秋田県', '石川県', '茨城県', '岩手県', '愛媛県', '大分県', '大阪府', '岡山県', '沖縄県', '香川県', '鹿児島県', '神奈川県', '岐阜県', '京都府', '熊本県', '群馬県', '高知>県', '埼玉県', '佐賀県', '滋賀県', '静岡県', '島根県', '千葉県', '東京都', '徳島県', '栃木県', '鳥取県', '富山県', '長崎県', '長野県', '奈良県', '新潟県', '兵庫県', '広島県', '福井県', '福岡県', '福島県', '北海道', '三重県', '宮城県', '宮崎県', '山形県', '山口県', '山梨県', '和歌山県'] 

// コマンドライン引数の準備
def cli = new CliBuilder(usage:"CliBuilder!")
cli.h('このヘルプ')
cli.p('都府県無しでも都府県扱いにする')
cli.m('一致した行のみ表示')
cli.f(longOpt: 'file', args:1, required:true, '解析するファイル')
cli.c(longOpt: 'column-index', args:1, required:true, '解析対象とする行のカラムのインデックス番号（0から始まる）')

def opts = cli.parse(args)
if (!opts) { // 必須パラメータが指定されていない場合もココ
    return
}
if (opts.h) {
    cli.usage()
    return
}

Closure getPrefs = { 
    opts.p ? prefs.collect{it.replaceAll(/[都府県]$/, '')} : prefs
}

Closure analyzer = {String line, String prefecture ->
    line =~ /.*${prefecture}(.*?).*/
}

new File(opts.f).readLines().collect {String line ->
    List<String> separetatdLine = line.split((/\s+(.*?)/))
    new Tuple2(line, getPrefs().findAll(analyzer.curry(separetatdLine[opts.c as Integer])))
}.findAll {
    opts.m ? it.second : it
}.each {
    println "${it.first} ${it.second.join(',')}"
}
```

```txt:data.txt
1        場所は東京都渋谷区
2        たぶん神奈川県、埼玉県、千葉県あたりが通勤可能圏内です
3        みかんといえば愛媛や和歌山や静岡など
4        東京ディスニーランドは千葉県にあります
5        北海道から沖縄まで
6        山口さんちのツムトくん
```

# 実行

```console:help
[koji:groovy]$ groovy hoge.groovy -h
error: Missing required options: f, c
usage: CliBuilder!
 -c,--column-index <arg>   解析対象とする行のカラムのインデックス番号（1から始まる）
 -f,--file <arg>           解析するファイル
 -h                        このヘルプ
 -m                        一致した行のみ表示
 -p                        都府県無しでも都府県扱いにする
```

```console:ベーシック
[koji:groovy]$ groovy hoge.groovy -f data.txt -c 1
1        場所は東京都渋谷区 東京都
2        たぶん神奈川県、埼玉県、千葉県あたりが通勤可能圏内です 神奈川県,埼玉県,千葉県
3        みかんといえば愛媛や和歌山や静岡など 
4        東京ディスニーランドは千葉県にあります 千葉県
5        北海道から沖縄まで 北海道
6        山口さんちのツムトくん 
[koji:groovy]$ 
```

```console:マッチした行のみ表示（-m)
[koji:groovy]$ groovy hoge.groovy -f data.txt -c 1 -m
1        場所は東京都渋谷区 東京都
2        たぶん神奈川県、埼玉県、千葉県あたりが通勤可能圏内です 神奈川県,埼玉県,千葉県
4        東京ディスニーランドは千葉県にあります 千葉県
5        北海道から沖縄まで 北海道
[koji:groovy]$ 
```

```console:都府県という末尾で終わっていなくても都道府県扱いにする（-p）
[koji:groovy]$ groovy hoge.groovy -f data.txt -c 1 -p
1        場所は東京都渋谷区 京都,東京
2        たぶん神奈川県、埼玉県、千葉県あたりが通勤可能圏内です 神奈川,埼玉,千葉
3        みかんといえば愛媛や和歌山や静岡など 愛媛,静岡,和歌山
4        東京ディスニーランドは千葉県にあります 千葉,東京
5        北海道から沖縄まで 沖縄,北海道
6        山口さんちのツムトくん 山口
[koji:groovy]$ 
```

```console:合わせ技
[koji:groovy]$ groovy hoge.groovy -f data.txt -c 1 -m -p
1        場所は東京都渋谷区 京都,東京
2        たぶん神奈川県、埼玉県、千葉県あたりが通勤可能圏内です 神奈川,埼玉,千葉
3        みかんといえば愛媛や和歌山や静岡など 愛媛,静岡,和歌山
4        東京ディスニーランドは千葉県にあります 千葉,東京
5        北海道から沖縄まで 沖縄,北海道
6        山口さんちのツムトくん 山口
[koji:groovy]$ 
```

# その他
Groovyでもそこまで行数増えないなぁという嬉しい誤算！
ただやはりテキスト処理系はPerlはやはり力を発揮するなということを実感しました。
あと今回のGroovyコードはいきなりドカっと-fで指定されたテキストの内容をメモリに読み込んでいるので、本来このような大量のデータが存在するであろう処理には向いていません。ちゃんと1行シークしていくようなコードを書くのがベターです。