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値の有りなし、順番任意に対しても対応しています。
0 件のコメント:
コメントを投稿