Shellで構築するSQL「ShellQL」を作ってみる #3「json2csv」

2015年8月21日

Shell テクノロジー プログラミング

JSONファイルをCSVファイルとKeyファイルに変換するshellスクリプトです。

概要

JSONファイルをCSVに変換するのは、さほど難しくないだろうと取り掛かったが、いくつかの困難があったので、メモとともにver 1.0を載せておきます。 ちなみに、この処理もjqモジュールのみ使用することになるので、事前インストールをお願いします。

苦労ポイント

当初は、jsonデータのkey値を除いたvalue値のみをカンマ区切りでテキスト化すればいいと考えてましたが、jsonファイルは、keyの並びが変更可能という点がカラム値固定のcsvと大きく違っている事に気が付きました。 また、同じような理由で、keyの存在も任意で行うことができるので、全てのレコードを一度検索して共通のkeyデータを作成しないといけないというところに気がついた時点で少し構築に時間を要しました。 あと、jqコマンドを使った際に、存在しないkeyがあると、nullという文字列が出力されるので、今回はnullをblankにして対応してます。 また、もともと「"flg":""」のように、blankになっているものは、jqコマンドの -r オプションをつけると、無視されてカラムの番地がずれる現象があったので、一括取得をせずに、1カラム毎にjqコマンドを実行してます。 もしかすると、この処理のせいで、大きなデータ対応が非常にレスポンス悪くなってしまうかもしれないので、これも以後バージョンで検討します。

プログラム

#!/bin/bash ## set-write-files csvFile="$1.csv" keyFile="$1.key" if [ -e ${csvFile} ];then rm ${csvFile} fi ## get-keys keys=() while read line do res=`echo ${line}|jq '.|keys'|jq -r '.[]'` arr=(`echo ${res}`); for i in ${arr[@]};do # check-key-exists if [ -z "`echo ${keys[@]}|grep \"$i\"`" ];then keys+=($i) fi done done< $1 ##output-keyfile echo `echo ${keys[@]}|tr -s " " ","` > ${keyFile} ## get-values while read line do data="" for i in ${keys[@]};do res=`echo ${line}|jq -r ".$i"` if [ "${res[@]}" == "null" ];then res="";fi data="${data}${res[@]},"; done echo ${data} >> ${csvFile} done< $1

使い方

# 元ファイル「hoge.json」 {"flg":"0","id":"001","name":"abcdefg","value":"test1"} {"flg":"0","id":"002","name":"hijklmn","test":"aaaa-aaa","value":"test2"} {"flg":"","id":"003","name":"opqrstu","value":"test3"} # 処理実行 $ bash json2csv.sh hoge.json # 出力-1 「hoge.json.csv」 flg,id,name,value,test # 出力-2 「hoge.json.csv」 0,001,abcdefg,test1,, 0,002,hijklmn,test2,aaaa-aaa, ,003,opqrstu,test3,,

注意点

jsonはネストは1階層のみを対象にしてます。 深度が複数バージョンはver 1.1で実現したいと思います。 ちなみに、key値の有りなし、順番任意に対しても対応しています。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ