linuxのコマンドだけでcsvを取り回してみる

皆さんシェル使ってますか。コマンド打ってますか。シェル芸便利ですよ。 と言うわけでコマンドでcsvを取り回す方法諸々です。 これだけで結構いろいろ出来るので、簡単なものならプログラミングもエクセルも必要なくて楽ちん。

カレントディレクトリにあるdata.csvを操作する、ということで説明を進めて参ります。 ここで取り上げたコマンドはすべて標準入力に対応していますので、引数でファイル名を渡す代わりにパイプなんかでデータを入れることも出来ます。

ソート

$ sort data.csv

これが一番シンプルな形。三通り書きましたが、全部結果は同じです。

$ sort -n data.csv

この様にすると、数値が入っているとみなしてソートします。

$ sort -h data.csv

こうすると10kとか2Gとかを認識してソートしてくれます。

$ sort -r data.csv

こうすれば逆順ソートも出来ます。

$ sort -k 3 -t ',' data.csv

これで3つめのカラムの値でソートできます。 tオプションを省略するとカラムがスペースで区切られていると仮定されるようです。

n行だけ切り出す / n行だけ切り捨てる

$ head -n 10 data.csv

先頭の10行だけを取り出し。簡単。

$ tail -n 10 data.csv

末尾の10行ならこんな感じ。tailになっただけです。

$ head -n +5 data.csv
$ tail -n +5 data.csv

こうすると先頭/末尾の5行を切り捨てます。

行を抽出する

$ grep abc data.csv

文字列abcが含まれている行を抽出します。 正規表現による部分一致ですので、完全一致にしたい場合は前後にカンマを入れる等の工夫が必要かもしれません。

$ awk -F, '$1 > 100{ print $0 }' data.csv

1列目の値が100より大きい行だけを抽出します。

$ awk -F, '($1 - $2)/$2 > 0.5{ print $0 }' data.csv

計算した結果を条件にしたりも出来ます。さすがシェル芸の代名詞awkさん。

列を抽出する

$ cut -d, -f1 data.csv

1列目だけを取り出します。

$ cut -d, -f1,3-5 data.csv

1列目と3列目から5列目までを取り出します。

$ cut -d, -f-2 data.csv

右から数えて2列だけ取り出します。

計算する

$ awk -F, '{ print ($1 + $2)/2 }'

1列目と2列目の値の平均を計算します。

$ awk -F, '{ sum += $3 } END{ print sum }'

3列目の合計値を計算します。

$ awk -F, '{ sum += $3 } END{ print sum/NR }'

3列目の平均値を計算します。

$ awk -F, 'max<$3 { max = $3 } END{ print sum/NR }'
$ awk -F, 'min>$3 || NR==0 { min = $3} END{ print min }'

3列目最大値と最小値を計算します。

$ awk -F, '{ sum += $3 } END{ print $3 "," sum "," sum/NR }'

もちろん複数の計算結果を一つの行に収めることも出来ますし、入力データをそのまま出力に入れることも出来ます。

行数を数える

$ grep -c '' data.csv

data.csvの行数を数えます。

$ grep -c . data.csv

これだと空行を除いた行数を数えます。

$ grep -c abc data.csv

abcと言う文字列が含まれる行の数を数えます。 部分一致になるので、完全一致にしたい場合はカンマで挟むか、awkを使うべきかもしれません。

$ awk -F, '$1>100{ count++ } END{ print sum }'

1列目が100より大きい行の数を数えます。


ひとまずこんなところで。

vimの矩形編集やらマクロやらでざくっとまとめてデータをcsvにして、後はコマンドでごりごり処理する。 みたいな使い方が出来るようになるとめちゃめちゃ強い気がする。頑張って修行しよう・・・。