jqコマンドをだいぶ使いこなしてきて、自作のフレームワークのデータベースへ組み込みもできる様になってきました。
世の中全てのデータがjsonでやりとりされればいいのですが、まだまだcsvデータも残っているのが現状です。
この間、金融庁でダウンロードしてきた株価データや企業情報、郵便局からダウンロードした郵便番号データなどは、余裕でcsvフォーマットです。
このcsvフォーマットというのは、文字エンコードが"Shift-JIS"という、サーバー業界で"UTF-8"を標準にしようと頑張っている中、トラブルも多いこのエンコード技術を使い続けていて、非常にやっかいです。
そう考えると、Shift-JISデータは、「古い」という感覚は拭えません。
とりあえず、文字エンコードはおいといて、とある会社の株価情報を取得したものをjqコマンドを使ってPHPに取り込んだ時のコマンドサンプルを掲載しておきます。
csvデータとコマンド
20181203,940,958,939,942,54600,942
20181204,852,890,851,868,391700,868
20181205,845,870,840,851,122500,851
20181206,854,855,798,807,146000,807
20181207,806,825,799,803,57700,803
20181210,805,805,770,772,82700,772
20181211,787,787,726,735,137200,735
20181212,740,779,740,775,72000,775
20181213,775,812,765,788,89900,788
20181214,773,781,744,749,75500,749
json形式でもないこのデータをどうやってjqコマンドで受け取るかというと・・・
jq -s -c -R '[ split("\n") | .[] | split(",") | {date: .[0] , start: (.[1] | tonumber?) , max : (.[2] | tonumber?) , min : (.[3] | tonumber?) , end : (.[4] | tonumber?) , volume : (.[5] | tonumber?)} ]' company.csv
解説
最初にsplitが2つ並んでいるのは、「改行コード」と「,カンマ」で縦横の分解をしています。
注意点としては、-sオプションの"--slurp"をつけることを忘れない様にしましょう。
※このオプションをつけていないと、最後に行毎のデータを配列として繋げなれなくなります。
マルチバイト文字列が入っている場合は、エンコード対応をしなければいけないのですが、今回は株価データということもあり、数値だけだったので、その点は楽できました。
※後日エンコードタイプもサンプルアップします。
csvは分解さえできてしまえば、あとは、単なる配列処理なので、出力用のjson形式を整えてあげるだけです。
しかしここでもう一つ落とし穴があり、数値データだけとはいえ、csvを分解するときに、全てのデータを文字列化してsplitを行うため、全ての値が"string"になってしまいます。
そして型変換のために、"tonumber"コマンドを使うといいでしょう。
このコマンドは、文字列化された数値を型変換してくれるのですが、数値の桁数が多い場合に入ってしまう","カンマなどがあると、数値化できずにエラーになってしまうので要注意です。
また、csvの場合は、空行なども存在するため、ブランク文字列に対してもエラーになってしまいます。
その場合は、tonumberの後ろに"?"をつけることで、エラー回避してくれるようになるので、禁則処理としてセットしておきましょう。
あっ!そういえば、","カンマが数値に含まれていると、splitで分解されてしまいますね。
そういうデータの含まれたcsvを使う場合は、別の分解方法を行わないといけないのですが、今回は手抜きでそこまで書きません。
今このデータが処理できればいいのです。
結果出力
[
{
"date": "20181203",
"start": 940,
"max": 958,
"min": 939,
"end": 942,
"volume": 54600
},
{
"date": "20181204",
"start": 852,
"max": 890,
"min": 851,
"end": 868,
"volume": 391700
},
{
"date": "20181205",
"start": 845,
"max": 870,
"min": 840,
"end": 851,
"volume": 122500
},
{
"date": "20181206",
"start": 854,
"max": 855,
"min": 798,
"end": 807,
"volume": 146000
},
{
"date": "20181207",
"start": 806,
"max": 825,
"min": 799,
"end": 803,
"volume": 57700
},
{
"date": "20181210",
"start": 805,
"max": 805,
"min": 770,
"end": 772,
"volume": 82700
},
{
"date": "20181211",
"start": 787,
"max": 787,
"min": 726,
"end": 735,
"volume": 137200
},
{
"date": "20181212",
"start": 740,
"max": 779,
"min": 740,
"end": 775,
"volume": 72000
},
{
"date": "20181213",
"start": 775,
"max": 812,
"min": 765,
"end": 788,
"volume": 89900
},
{
"date": "20181214",
"start": 773,
"max": 781,
"min": 744,
"end": 749,
"volume": 75500
}
]
うむ、なんのも問題もなくクリアできました。
とはいってもこの処理を作るのに、ハマりまくって半日費やしたんですけどね!
0 件のコメント:
コメントを投稿