「grep」などの簡単なツールを使用して、キーおよび/または値を取得したい、大きくて比較的複雑なjson設定ファイルがあります。 「grep」の場合、出力のファイルにキーへのフルパスと最終値につながる各サブキー/配列が含まれることを望みます。
これは、大規模ファイルシステムでファイル/ディレクトリを検索し、「find」コマンドを使用するのと同じように、ファイル/ディレクトリが見つかった場合は、そのファイル/ディレクトリのフルパスを表示できるようになります。
また、私が達成したいのと同様の比較は、より簡単な検索と報告のためにxmlファイルをキー/値パスに変換するxml2ユーティリティです。
私は "keys"コマンドを使用してjsonファイルを解析するために "jq"ユーティリティを使用してきました。私はjsonキーパスの最初の分岐に移動する粗雑なbashスクリプトを作成しましたが、json構造のツリー全体を再帰的に上下に移動する簡単な方法が見つかりませんでした。
以下は、bashスクリプトで実行したい操作の手動指示です。はい、とても非効率的ですが、パフォーマンスが向上する前には試してみることができると思います!
複雑な構成を含むfile.jsonが与えられたら、キーを使用して最初のエントリを取得し、キーを取得したら、それを別の反復で使用して次のキーを取得するように分岐の終わりに達するまで続けます。 ..
cat file.json | jq '. | keys | .[]'
cat file.json | jq '.Blueprints | keys | .[]'
cat file.json | jq '.Blueprints.security | keys | .[]'
cat file.json | jq '.Blueprints.security.kerberos_descriptor | keys | .[]'
cat file.json | jq '.Blueprints.security.kerberos_descriptor.identities | keys | .[]'
最終結果は次のとおりです。
."Blueprints"."security"."kerberos_descriptor"."identities"[0]."keytab"."configuration"."cluster-env/smokeuser_keytab"
しかし、もちろん、これは非常に大きなキー/値ツリーの最初の分岐です。
答え1
jq
役立つ可能性があるいくつかの適切な組み込み機能があります。 Bash技術はあまり必要ありませんし、この問題を解決するのには適していません。これは必要に応じて変更できるjqの非常に明示的なバージョンです。
jq -r '. as $root |
path(..) | . as $path |
$root | getpath($path) as $value |
select($value | scalars) |
([$path[] | @json] | join(".")) + " = " + ($value | @json)
' < file.json
それを使う変数バインディング演算子... as $identifier |
計算された値を名前で数回覚えてください。そのうちのいくつかは不要ですが、議論を簡単にします。これらの行のそれぞれは、プログラムの残りの部分の変数を$x
左の値にバインドします。
これpath/1
機能ここのキーで、基本的に必要な操作を行います。path(..)
オブジェクトに入れ子になった各値を取得するために繰り返す必要があるすべてのキーを含む配列を作成します。各パスには次の形式があります。
[ "Blueprints", "security", "kerberos_descriptor" ]
他の配列と同じ方法で使用され、パスを解釈する特別な関数で使用することもできます。
path(..) | . as $path |
具体的にループを定義します。ファイルの各パスに対してループを呼び出し、残りの$path
プログラムをループ本体として実行します。プログラムの残りの部分は選択と出力であるため、パスごとにチェックされて出力ラインが生成されることがあります。
getpath
次のパス配列のいずれかを読んでください。識別する値を抽出します。select
フィルタリングしようテストに合格した値のみを選択 - ここでは、次の基準を満たす値のみを選択スカラー(数値、文字列、ブール値または null) なので、中間オブジェクトと配列は無視されます (null 値も同様)。
最後の行は出力形式を次のように設定します。
"abc"."def".3."xyz" = true
ファイルの各値は1行に1つずつあり、必要に応じて調整できます。繰り返し参照できるファイルにリダイレクトしますgrep
。
@json
値を正しく引用し、残りは必要な形式に合わせて簡単に変更できる必要があります。join
他の場合、点としてマークされた関数を手動でコピーすることは非常に複雑なので、配列に角かっこを使用しません。両側に括弧が必要です。