1. jq - JSON 用 sed
JSONは、特にAPIが普及した今、ますます人気が高まっています。私はJSONを扱っていて、grepやsedを使って醜いコードを書いていたことを覚えています。jqのおかげで、やっと醜いコードを書くのをやめることができます。
2008年の大統領選挙ですべての候補者に関心があるとします。New York Timesは選挙資金に関するAPIを持っています:
curl -s '"http://..com/svc/elections/us/v3/finances/2800"/president/.json?api-key=super-secret' > .json
sはサイレントモードを示します。そしてjqの最も単純なフォーマットであるjq '.' を使います。と書くと、醜いコードが表示されます:
{"status":"OK","base_uri":"http://..com/svc/elections/us/v3/finances/2800"/","cycle":2008,"":" (c) 2013 The New York Times Company. All Rights Reserved.","results":[{"candidate_name":"Obama, Barack","name":"Barack Obama","party":"D",
素敵なフォーマットに変換します:
< nyt.json jq '.' | head { "results": [ { "candidate_id": "P80003338", "date_coverage_from": "2007-01-01", "date_coverage_to": "2008-11-24", "candidate_name": "Obama, Barack", "name": "Barack Obama", "party": "D",
また、jqはJSONデータを選択し、フィルタリングすることができます:
< nyt.json jq -c '.results[] | {name, party, cash: .cash_on_hand} | select(.cash | tonumber > 1000000)'
{"cash":"29911984.0","party":"D","name":"Barack Obama"}
{"cash":"32812513.75","party":"R","name":"John McCain"}
{"cash":"4428347.5","party":"D","name":"John Edwards"}
Unixの哲学は、一つのことをうまくこなすプログラムを書くことですが、jqは強力です!json2csvの紹介です。
2. json2csv - JSONをCSVに変換します。
JSONはデータ交換には適していますが、多くのコマンドラインツールには適していません。しかしご心配なく。json2csvを使えば、JSONをCSVに簡単に変換できます。 million.jsonにデータがあるとします。
< million.json json2csv -k name,party,cash
その後、データを変換することができます:
Barack Obama,D,29911984.0
John McCain,R,32812513.75
John Edwards,D,4428347.5
CSVフォーマットでは、cut -dやawk -Fのような伝統的なツールを使うことができます。CSVは表形式で保存されるため、csvkitの作者はcsvkitを開発しました。
3. csvkit - CSV の変換と使用スイート
csvkitは単なるプログラムではなく、一連のプログラムです。これらのツールのほとんどは、CSVデータにテーブルヘッダがあることを「想定」しているので、ここにその1つを示します。
echo name,party,cash | cat - million.csv > million-header.csv
csvsort を使って候補者を選挙資金でソートし、表示することができます:
< million-header.csv csvsort -rc cash | csvlook
|---------------+-------+--------------|
| name | party | cash |
|---------------+-------+--------------|
| John McCain | R | 32812513.75 |
| Barack Obama | D | 29911984.0 |
| John Edwards | D | 4428347.5 |
|---------------+-------+--------------|
MySQLのようですね。データベースといえば、以下のコマンドでCSVをsqliteデータベースに書き込むことができます:
csvsql --db sqlite:///myfirst.db --insert million-header.csv
sqlite3 myfirst.db
sqlite> .schema million-header
CREATE TABLE "million-header" (
name VARCHAR(12) NOT NULL,
party VARCHAR(1) NOT NULL,
cash FLOAT NOT NULL
);
CSVでも書式設定が可能なため、挿入後のデータは正しくなります。さらに、このスイートにはin2csv、csvgrep、csvjoinなど、他にも興味深いツールがあります。csvjsonを使えば、データをcsvからjsonに変換することもできます。
scrape - XPath と CSS セレクタによる HTML 情報抽出ツール
scrapeはPythonスクリプトで、特定のHTML要素を選択できるようにlxmlとcssselectパッケージを含んでいます。ウィキペディアには、全ての国の国土面積に対する国境言語の比率をリストアップしたページがあるので、その比率情報を抽出する方法を紹介します。
curl -s 'http://..org/wiki/List_of_countries_and_territories_by_border/area_ratio' | scrape -b -e '.wikitable > tr:not(:first-child)' | head
<!DOCTYPE html>
<html>
<body>
<tr>
<td>1</td>
<td>Vatican City</td>
<td>3.2</td>
<td>0.44</td>
<td>7.2727273</td>
</tr>
bコマンドは、xml2jsonがHTMLをJSONに変換するのに必要な場合があるので、タグを含めるようにscrapeに指示します。
xml2json - XMLからJSONへの変換
その名の通り、XML(HTMLもXMLの一種)をJSON出力形式に変換するツールです。従って、xml2jsonはscrapeとjqの良い橋渡しとなります。
curl -s 'http://..org/wiki/List_of_countries_and_territories_by_border/area_ratio' | scrape -be '.wikitable > tr:not(:first-child)' | xml2json | jq -c '...tr[] | {country: .td[1][], border: .td[2][], surface: .td[3][], ratio: .td[4][]}' | head
{"ratio":"7.2727273","surface":"0.44","border":"3.2","country":"Vatican City"}
{"ratio":"2.2000000","surface":"2","border":"4.4","country":"Monaco"}
{"ratio":"0.6393443","surface":"61","border":"39","country":"San Marino"}
{"ratio":"0.4750000","surface":"160","border":"76","country":"Liechtenstein"}
{"ratio":"0.3000000","surface":"34","border":"10.2","country":"Sint Maarten (Netherlands)"}
{"ratio":"0.2570513","surface":"468","border":"120.3","country":"Andorra"}
{"ratio":"0.2000000","surface":"6","border":"1.2","country":"Gibraltar (United Kingdom)"}
{"ratio":"0.1888889","surface":"54","border":"10.2","country":"Saint Martin (France)"}
{"ratio":"0.1388244","surface":"2586","border":"359","country":"Luxembourg"}
{"ratio":"0.0749196","surface":"6220","border":"466","country":"Palestinian territories"}
もちろん、JSONデータは後からjson2csvに入力することもできます。
6. サンプル - デバッグに使用します。
大量のデータを扱う場合、デバッグ・パイプラインは非常に厄介です。そんな時にsampleが役に立ちます。このツールには3つの使い方があります:
- データの一部を行ごとに表示します。
- 出力に遅延を加えるには、データが多少遅れて入ってきたり、出力が速すぎてはっきり見えないときに、これを使うととても便利です。
- プログラムの実行時間を制限します。
次の例は、これら3つの機能を示しています:
1 | seq 10000 | sample -r 20% -d 1000 -s 5 | jq '{number: .}' |
これは、各行が20%の確率でjqに与えられ、行間には1000ミリ秒の遅延があり、サンプルは5秒後に停止することを意味します。これらのオプションはオプションです。不必要な計算を避けるために、できるだけ早い段階でサンプリングして、デバッグして遊んだ後に削除できるようにしましょう。
7.リオ - 治療にRを加える
この記事はRなしでは完結しません。処理にR/Rscriptを追加しても、入力と出力が標準化されていないのであまり理解できません。
Rioは次のように動作します:まず、標準入力に与えられたCSVを一時ファイルに移動し、それをdfに読み込むようにRに指示します。その後、-eのコマンドが実行されます。***あるコマンドの出力が標準出力にリダイレクトされます。これら3つの使い方を1行のコマンドで示し、それぞれの部分を5桁の数字で要約して示します:
curl -s 'https://..com/pydata/pandas/master/pandas/tests/data/.csv' > .csv
< iris.csv Rio -e 'summary(df)'
SepalLength SepalWidth PetalLength PetalWidth
Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
Median :5.800 Median :3.000 Median :4.350 Median :1.300
Mean :5.843 Mean :3.054 Mean :3.759 Mean :1.199
3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
Name
Length:150
Class :character
Mode :character
sオプションを付けると、sqldfパッケージが導入され、CSV形式で出力されるようになり、後で別のツールでデータを処理できるようになります。
< iris.csv Rio -se 'sqldf("select * from df where df.SepalLength > 7.5")' | csvlook
|--------------+------------+-------------+------------+-----------------|
| SepalLength | SepalWidth | PetalLength | PetalWidth | Name |
|--------------+------------+-------------+------------+-----------------|
| 7.6 | 3 | 6.6 | 2.1 | Iris-virginica |
| 7.7 | 3.8 | 6.7 | 2.2 | Iris-virginica |
| 7.7 | 2.6 | 6.9 | 2.3 | Iris-virginica |
| 7.7 | 2.8 | 6.7 | 2 | Iris-virginica |
| 7.9 | 3.8 | 6.4 | 2 | Iris-virginica |
| 7.7 | 3 | 6.1 | 2.3 | Iris-virginica |
|--------------+------------+-------------+------------+-----------------|
gオプションを使うと、ggplot2が参照され、g got with dfというggplotオブジェクトが宣言されます。最終出力がggplotオブジェクトの場合、PNGが標準出力に書き出されます。
< iris.csv Rio -ge 'g+geom_point(aes(x=SepalLength,y=SepalWidth,colour=Name))' > iris.png
このツールは、コマンドラインから R の力をフルに活用できるようにするために作りました。もちろん多くの欠点がありますが、少なくとも gnuplot を学ぶ必要はもうありません。
コマンドラインツール
twitterやハッカーニュースを通じて他の友人から勧められたツールを紹介します。
- BigMLer by aficionado
- crush-toolsmjn
- csv2sqlite by dergachev
- csvquote by susi22
- data-tools repositorycgrubb
- feedgnuplot by dima55
- Grinder repository by @cgutteridge
- HDF5 Tools by susi22
- littler by @eddelbuettel
- malletgibrown
- RecordStreamRecordStream
- subsample by paulgb
- xls2csv by @sheeshee
- XMLStarlet by gav
はんけつをくだす
私が日常的に使っている7つのコマンドラインツールを紹介しました。それぞれのツールにはそれぞれの強みがありますが、私はよく従来のツールと組み合わせて使っています。小さなツールを組み合わせて使うことで、大きなパイプラインを形成することができるのです。
皆さんはこのリストをどう思いますか?また、普段どんなツールを使うのが好きですか?皆さんも何か面白いツールを作ったら、遠慮なくデータサイエンス・ツールボックスdata science toolboxに追加してください。
ツールを作れないと思っても心配しないでください。今度変わったコマンドラインパイプラインを書いたら、それを#付きのファイルに入れることを忘れないでください!を付けてファイルに書き出し、引数を追加して実行ファイルに変更すれば、ツールの完成です!
ご興味のある方は、お気軽にください。





