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コマンドを使ってください。めちゃくちゃ便利です。
例えば、上記のコマンドと同じ処理をxsvでやる場合、こんな書き方になる。
xsv select 2 test.csv
"hello, world"
はい、強い。ちゃんと文字列内のカンマに惑わされずに2列目の値を持って来れている。やはり餅は餅屋。CSVのパースはCSVパース専用のコマンドに限る。他にもsortとかsearchとか、さらにはCSV同士のJOINなんかもできるめちゃくちゃ高機能なコマンドなので、業務でCSVをいじいじするエンジニアはぜひとも使ってほしい。