CSVファイルの加工について調べていたところ、Rustで書かれたCSVの集計・加工ツール『xsv』コマンドなるものがあると知ったのでちょっと触ってみた。
1.インストール
まずはインストールから。
インストールの方法は2種類あり、ひとつはコンパイル済みのバイナリをそのまま使う方法、もう一つは自分でコンパイルする方法だ。
バイナリをそのままダウンロードしてくる
バイナリをそのままダウンロードする場合、以下のようにする(念のため、こちらで最新版のURLを確認しておくことをすすめる)。
wget https://github.com/BurntSushi/xsv/releases/download/0.9.14/xsv-0.9.14-x86_64-unknown-linux-gnu.tar.gz
tar xzvf xsv-0.9.14-x86_64-unknown-linux-gnu.tar.gz
sudo sh -c 'cp xsv-0.9.14-x86_64-unknown-linux-gnu/xsv /usr/local/bin/'
コンパイルする
コンパイルを行う場合、Rustのパッケージマネージャーである『Cargo』を入れるといいようだ。
今はRustのインストールと同時に自動的に入ってくるので、以下のコマンドでRustをインストールする。
curl -s https://static.rust-lang.org/rustup.sh | sh -s
Rustインストール後、以下のコマンドでxsvをコンパイル、インストールを行う。
git clone git://github.com/BurntSushi/xsv
cd xsv
cargo build --release
2.触ってみる
無事インストールが終わったら、実際にxsvコマンドでCSVファイルをいじってみよう。
サンプル用にcsvファイルをダウンロードしてくる。
curl -LO http://burntsushi.net/stuff/worldcitiespop.csv
xsvコマンドは、サブコマンドを使ってcsvを加工するスタイルだ。
いくつかのサブコマンドを抜粋して使ってみる。
CSVのヘッダーを確認する
以下のようにコマンドを実行することで、CSVのヘッダーを確認することができる。
xsv headers ファイルPATH
blacknon@BS-PUB-UBUNTU-01:~$ head -10 worldcitiespop.csv
Country,City,AccentCity,Region,Population,Latitude,Longitude
ad,aixas,Aixas,06,,42.4833333,1.4666667
ad,aixirivali,Aixirivali,06,,42.4666667,1.5
ad,aixirivall,Aixirivall,06,,42.4666667,1.5
ad,aixirvall,Aixirvall,06,,42.4666667,1.5
ad,aixovall,Aixovall,06,,42.4666667,1.4833333
ad,andorra,Andorra,07,,42.5,1.5166667
ad,andorra la vella,Andorra la Vella,07,20430,42.5,1.5166667
ad,andorra-vieille,Andorra-Vieille,07,,42.5,1.5166667
ad,andorre,Andorre,07,,42.5,1.5166667
blacknon@BS-PUB-UBUNTU-01:~$ xsv headers worldcitiespop.csv
1 Country
2 City
3 AccentCity
4 Region
5 Population
6 Latitude
7 Longitude
CSVの行数を取得する
CSVの行数を取得する場合は、以下のようにする。
wcの結果と比べて一行少ないのは、ヘッダーを含めないからだ。
xsv count ファイルPATH
blacknon@BS-PUB-UBUNTU-01:~$ wc worldcitiespop.csv
3173959 5681543 151488712 worldcitiespop.csv
blacknon@BS-PUB-UBUNTU-01:~$ wc -l worldcitiespop.csv
3173959 worldcitiespop.csv
blacknon@BS-PUB-UBUNTU-01:~$ xsv count worldcitiespop.csv
3173958
コンソール上で読みやすいようにテーブル状にする
「table」サブコマンドを使うことで、コンソール上で読みやすいようにテーブル上に出力させることができる。
xsv table ファイルPATH
blacknon@BS-PUB-UBUNTU-01:~$ cat /tmp/test.csv
id,user,value
1,aaa,1223
2,bbb,3333
3,ccc,855
4,ddd,998
5,eee,24354
6,fff,345
7,ggg,325
8,hhh,22
9,iii,4657
10,jjj,896
blacknon@BS-PUB-UBUNTU-01:~$ xsv table /tmp/test.csv
id user value
1 aaa 1223
2 bbb 3333
3 ccc 855
4 ddd 998
5 eee 24354
6 fff 345
7 ggg 325
8 hhh 22
9 iii 4657
10 jjj 896
指定された行数をランダムでサンプリング抽出する
サブコマンド「sample」で、既存のCSVファイルからランダムに行を抽出させることもできる。
xsv sample 抽出する行数 ファイルPATH
blacknon@BS-PUB-UBUNTU-01:~$ xsv sample 10 worldcitiespop.csv | xsv table
Country City AccentCity Region Population Latitude Longitude
ir band-i-kariz Band-i-Kariz 42 35.504858 58.211005
nl keup Keup 05 51.310603 5.985442
co gallinazo Gallinazo 35 9.318912 -74.915084
al hendek i goges Hendek i Goges 48 41.6402778 19.6458333
mx la puerta de agua caliente La Puerta de Agua Caliente 11 20.224167 -101.681111
br cunha Cunha 15 -20.333333 -42.966667
cn wulihotzutsun Wulihotzutsun 05 43.459722 126.483333
lv riebiki Riebiki 29 57.0166667 22.7833333
id tjihandjawar Tjihandjawar 30 -7.0347 107.3194
eg at tall al kafr al gharbi At Tall al Kafr al Gharbi 07 30.5563889 31.7786111
CSVファイルのインデックスを作成する
サイズの大きいCSVファイルを取り扱う場合、処理の前にインデックスを作成しておくことができる。
xsv index ファイルPATH
blacknon@BS-PUB-UBUNTU-01:~$ time xsv count worldcitiespop.csv
3173958
real 0m1.386s
user 0m1.280s
sys 0m0.096s
blacknon@BS-PUB-UBUNTU-01:~$ xsv index worldcitiespop.csv
blacknon@BS-PUB-UBUNTU-01:~$ time xsv count worldcitiespop.csv
3173958
real 0m0.039s
user 0m0.032s
sys 0m0.004s
CSVファイル全体の統計分析を行う
CSVファイル全体の統計分析を行う場合、サブコマンド「stats」を使うとよいだろう。
xsv stats ファイルPATH # CSV全体での統計
xsv stats -s カラム名 ファイルPATH # 特定のカラムを指定して統計
xsv stats --cardinality ファイルPATH # カーディナリティも出力する
blacknon@BS-PUB-UBUNTU-01:~$ xsv stats worldcitiespop.csv | xsv table
field type min max min_length max_length mean stddev
Country Unicode ad zw 2 2
City Unicode bab el ahmar Tykkvibaer 1 91
AccentCity Unicode Bab el Ahmar in Bou Chella 1 91
Region Unicode 00 Z9 0 2
Population Integer 7 31480498 0 8 47719.570633597104 302885.55920403753
Latitude Float -54.933333 82.483333 1 12 27.188165808469346 21.952613849125445
Longitude Float -179.9833333 180 1 14 37.08885989656549 63.22301045924227
blacknon@BS-PUB-UBUNTU-01:~$ xsv stats -s Population worldcitiespop.csv | xsv table
field type min max min_length max_length mean stddev
Population Integer 7 31480498 0 8 47719.570633597104 302885.55920403753
blacknon@BS-PUB-UBUNTU-01:~$ xsv stats -s Population --cardinality worldcitiespop.csv | xsv table
field type min max min_length max_length mean stddev cardinality
Population Integer 7 31480498 0 8 47719.570633597104 302885.55920403753 28754
CSVから特定の列のみ表示させる
CSVファイルから特定の列だけを抜き出す場合は、「select」で列名を指定してやればよい。
xsv select 列名1,列名2,... ファイルPATH
blacknon@BS-PUB-UBUNTU-01:~$ head worldcitiespop.csv | xsv table
Country City AccentCity Region Population Latitude Longitude
ad aixas Aixas 06 42.4833333 1.4666667
ad aixirivali Aixirivali 06 42.4666667 1.5
ad aixirivall Aixirivall 06 42.4666667 1.5
ad aixirvall Aixirvall 06 42.4666667 1.5
ad aixovall Aixovall 06 42.4666667 1.4833333
ad andorra Andorra 07 42.5 1.5166667
ad andorra la vella Andorra la Vella 07 20430 42.5 1.5166667
ad andorra-vieille Andorra-Vieille 07 42.5 1.5166667
ad andorre Andorre 07 42.5 1.5166667
blacknon@BS-PUB-UBUNTU-01:~$ xsv headers worldcitiespop.csv
1 Country
2 City
3 AccentCity
4 Region
5 Population
6 Latitude
7 Longitude
blacknon@BS-PUB-UBUNTU-01:~$ xsv select Country,Region worldcitiespop.csv | head | xsv table
Country Region
ad 06
ad 06
ad 06
ad 06
ad 06
ad 07
ad 07
ad 07
ad 07
CSVの特定の行範囲を抜き出す
「split」サブコマンドで、CSVから特定の行~行を抜き出すように指定させることができる。
xsv slice -s 開始行 -e 終了行 ファイルPATH
blacknon@BS-PUB-UBUNTU-01:~$ xsv slice -s 10 -e 20 worldcitiespop.csv | xsv table
Country City AccentCity Region Population Latitude Longitude
ad andorre-vieille Andorre-Vieille 07 42.5 1.5166667
ad ansalonga Ansalonga 04 42.5666667 1.5166667
ad anyos Anyos 05 42.5333333 1.5333333
ad arans Arans 04 42.5833333 1.5166667
ad arinsal Arinsal 04 42.5666667 1.4833333
ad aubinya Aubinya 06 42.45 1.5
ad auvinya Auvinya 06 42.45 1.5
ad bicisarri Bicisarri 06 42.4833333 1.4666667
ad bixessarri Bixessarri 06 42.4833333 1.4666667
ad bixisarri Bixisarri 06 42.4833333 1.4666667
CSVの検索をする
CSV内の検索を行う場合は、サブコマンド「search」で行える。
xsv search キーワード ファイルPATH
xsv search -s 検索の対象列 キーワード ファイルPATH
blacknon@BS-PUB-UBUNTU-01:~$ xsv search Japan worldcitiespop.csv | xsv sample 10 | xsv table
Country City AccentCity Region Population Latitude Longitude
bo nuevo japan Nuevo Japan 04 -15.35 -68.0666667
id japanan Japanan 07 -7.571667 110.856111
us japan Japan PA 40.9925000 -75.9105556
id japanan Japanan 10 -7.734444 110.293056
id japanan kidul Japanan Kidul 08 -7.4246 112.3969
my rumah japang Rumah Japang 11 2.066667 112.416667
id japan Japan 07 -7.449167 110.281944
us japanese village one Japanese Village One HI 20.9052778 -156.4213889
id japan lor Japan Lor 07 -6.6665 110.9096
us japan Japan MO 38.2391667 -91.3058333
blacknon@BS-PUB-UBUNTU-01:~$ xsv search -s Country jp worldcitiespop.csv | xsv sample 10 | xsv table
Country City AccentCity Region Population Latitude Longitude
jp heita Heita 16 39.233333 141.883333
jp funatsu Funatsu 27 32.766667 130.033333
jp hama-koshimizu Hama-koshimizu 12 43.925 144.454167
jp kokubu Kokubu 32 34.566667 135.633333
jp okata Okata 40 34.783333 139.383333
jp takatsuki Takatsuki 42 36.75 137.316667
jp kinetambefutaroppu Kinetambefutaroppu 12 43.766667 144.183333
jp toseppu Toseppu 12 42.05 143.316667
jp kobama Kobama 47 24.337665 123.967611
jp miake Miake 24 38.419451 141.038796
CSVファイルの結合をする
xsvコマンドでは、サブコマンド「join」で指定したカラム同士でCSVファイルを結合させることができる。
xsv join --no-case カラム名1 CSVファイル1 カラム名2 CSVファイル2
blacknon@BS-PUB-UBUNTU-01:~$ xsv headers worldcitiespop.csv
1 Country
2 City
3 AccentCity
4 Region
5 Population
6 Latitude
7 Longitude
blacknon@BS-PUB-UBUNTU-01:~$ xsv headers countrynames.csv
<span style="color: #0000ff;">1 Abbrev
2 Country</span>
blacknon@BS-PUB-UBUNTU-01:~$ xsv join --no-case Country sample.csv Abbrev countrynames.csv | xsv sample 10 | xsv table
Country City AccentCity Region Population Latitude Longitude Abbrev Country
fr trois-palis Trois-Palis B7 45.633333 .05 FR France
cf wama Wama 02 4.3 21.65 CF Central African Republic
pg nagamize Nagamize 09 -6.0333333 145.4166667 PG Papua New Guinea
cn jihuizhou Jihuizhou 03 29.298401 116.728288 CN China
cn fubian Fubian 32 31.284892 102.476942 CN China
gb barby Barby J1 52.316667 -1.2 GB Great Britain | UK | England | Scotland | Wales | Northern Ireland | United Kingdom
af jija Jija 06 32.839626 61.985546 AF Afghanistan
ir qareh kahal Qareh Kahal 32 37.622778 48.434722 IR Iran
bd char salda Char Salda 81 23.6833333 89.8166667 BD Bangladesh
et didu Didu 54 7.016667 37.733333 ET Ethiopia</pre>
結構便利そうなコマンドだ。