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 1 Abbrev 2 Country 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
結構便利そうなコマンドだ。