2014/07/31

ShellScript - jq、xmllintコマンドさようなら。俺はパイプが好きだから - Qiita

UNIX哲学の一つとしてよく引用されるマイク・ガンカーズの教義に

  • 1.小さいものは美しい。
  • 2.1つのプログラムには1つのことをうまくやらせよ。

というのがあるが、まずこれができていない

http://qiita.com/richmikan@github/items/e051b5d882c3dd2a39c6

昔の UNIX で扱っていたデータはだいたい行指向でした。そして UNIX は行指向データを扱う為の OS と言っても過言ではありませんでした。 しかし JSON はどうでしょう。JSON は行指向ではありません。ならばツールを変えるのが正しい選択だと思いますし、そこでシェルを選ぶのは正直マニアの方しかいませんよね。 入力データがバイナリであれば、ツールも変えるはずです。JSON もそうすべきだと僕は思います。

理由1. 一つのことをうまくやっていない

ShellScript - jq、xmllintコマンドさようなら。俺はパイプが好きだから - Qiita

JSON だけを扱っていますすし、他のデータを扱ってはいないですよね。

理由2. フィルターとして振る舞うようになりきれてない

ShellScript - jq、xmllintコマンドさようなら。俺はパイプが好きだから - Qiita

jq は JSON の grep 的な存在だと思っています。僕は jq を使いこなしている訳ではないし、「便利だなー」くらいにしか思っていませんが、JSON をシェルで扱いたいと思った場合にはJSON が苦無く扱える言語やツールを選びます

ちなみに jq だと上記の問題はどの様に解決出来るか試してみました。

#!/bin/bash

FILE=$1
cat $FILE | jq -r 'paths|map(if type=="number" then "["+tostring+"]" else "["+tojson+"]" end)|join("")' |\
while read line; do
    value=`cat $FILE | jq -r ".$line|if type==\"string\" or type==\"number\" then \"MATCH:\"+tostring else empty end"`
    if [ "x$value" != "x" ]then
        echo $value sed "s/^MATCH:/.$line\t/"
    fi
done

実行結果は以下の通り。

.["会員名"] 文具 太郎
.["購入品"][0]  はさみ
.["購入品"][1]  ノート(A4,無地)
.["購入品"][2]  シャープペンシル
.["購入品"][3]["取寄商品"]  替え芯
.["購入品"][4]  クリアファイル
.["購入品"][5]["取寄商品"]  6穴パンチ

パスは jq のパス式です。短くていいですね。

ネタだったら、マジレスごめんなさい

Posted at 19:03 | WriteBacks () | Edit
Edit this entry...

wikieditish message: Ready to edit this entry.






















A quick preview will be rendered here when you click "Preview" button.