CSVで特定の列を抽出するならcutコマンドではなくxsvコマンドを使うべき

CSVで特定の列を抽出し、何らかの処理を加えたい場合は割とよくある。そんな時に書きがちなのが以下のようなコマンドだ。

cat test.csv | cut -d,  -f 2

これでCSVの1列目だけを抽出できるというわけだ。めでたしめでたし...。

とはならない。この方法には問題点がある。

CSVのデータに区切り文字以外のカンマが含まれる場合に正しく動かない

これが一番の理由だ。CSVのパース処理を既存のパーサーを使わずにオレオレ実装したりしても同じ問題が起きる。例えば以下のようなCSVが存在する。

"1","hello, world","400"

これに対して先述のコマンドを投げるとどうなるか。

cat test.csv  | cut -d, -f 2
"hello

と、こんな感じで2列目全体ではなく文字列の一部が抽出されてしまっている。それはそうだ。だってcutコマンドはCSVをパースするコマンドではなくて、「区切り文字を指定してn列目を抽出する」コマンドなのだから、そんなこと考慮してくれるはずもない。これが最初の問題点。
※ ただし、抽出したい列までに数字データしか入っていない場合はこの方法でも問題ない。ただ、こんな面倒なことをいちいち検証したくない。

じゃあ何を使うべきなのか

xsvコマンドを使ってください。めちゃくちゃ便利です。

github.com

例えば、上記のコマンドと同じ処理をxsvでやる場合、こんな書き方になる。

xsv select 2 test.csv 
"hello, world"

はい、強い。ちゃんと文字列内のカンマに惑わされずに2列目の値を持って来れている。やはり餅は餅屋。CSVのパースはCSVパース専用のコマンドに限る。他にもsortとかsearchとか、さらにはCSV同士のJOINなんかもできるめちゃくちゃ高機能なコマンドなので、業務でCSVをいじいじするエンジニアはぜひとも使ってほしい。