ファイルのリストを含むファイルを繰り返すbashスクリプトを作成しようとしています(各ファイルを繰り返します)。ファイルが開いたら、別のプログラム(jq)を使用してJSONファイルのキーと値のペアから値を抽出したいと思います。これまで私が作業している作業は次のとおりです。非常に基本的な作業を維持することで、何が間違っているのかを理解しようとすることができます。 jqコマンドは気にしません。動作しています。すべてのファイルを繰り返して単一のキーの値を抽出できますが、各キーに対して手動で変更する必要があるため、最終的には非常に退屈です。 。
簡単に言うと: 「マスター」は、開こうとしている各JSONファイルのフルパスを含むファイルです。 「key.txt」は、これらのJSONファイルから可能なすべてのキーを含むファイルです。 $ KEYは、開かれたファイルからその特定のキーを検索し、そのキーの値を返すjqの構文です。メインリストのファイルを開き、可能なすべてのキーを繰り返し、そのキーの値を "list.txt"というテキストファイルとして返したいと思います。
どんな助けでも大変感謝します。
#!/bin/bash
master="path/masterlist.txt"
while read master
do
for KEY in 'key.txt'
do
jq '. .'$KEY'' $f
echo $KEY
done >> list.txt
echo $master
done < list.txt
答え1
これはより多くの経験を得たので、今すぐ訪れる古い答えですjq
。
問題のユーザーはこう言いました。
私はjqコマンドに興味がありません[...]
...しかし、実際にjq
これを効率的に実行するには、コマンドが重要です。
要約すると、ユーザーはテキストファイル.txtにリストされているすべてのキーのすべての値を抽出しようとしますkeys.txt
。彼らは他のファイル.txtにリストされているすべてのJSONファイルに対してこれを行いたいと思いますlist.txt
。
、、、を使用してファイルセット、、a
キーセットb
のすべての(デコードされた)値を取得するには、次のようにします。c
file1
file2
file3
jq
jq -r '.[$ARGS.positional[]] // empty' file1 file2 file3 --args a b c
これはキーとして使用された文字列をに渡しjq
、それを配列の要素として受け入れます$ARGS.positional
。配列が拡張され、その要素は入力から値を取得するためのキーとして使用されます。ここでは、empty
キー値が存在しない場合、または何も返さないことを選択しましたnull
。
ファイルリストとキーリストの両方がランダムに長くなる可能性があり、両方のファイルに必要に応じて引用符付きの行が含まれていると仮定し、このタスクの中心にシェルパイプを追加します。
xargs sh -c '
xargs jq -r ".[\$ARGS.positional[]] // empty" "$@" --args <keys.txt
' sh <list.txt >result.txt
ファイル名のリストを取得し、短いインラインシェルスクリプトを呼び出してファイルをバッチ処理します。インラインスクリプトは、指定されたファイル名()とキーリストから読み取られた一連のキーでxargs
呼び出されます。jq
"$@"
結果値のリストが作成されますresult.txt
。
前の答えは次のとおりです。
あなたがしたいと言ったことを読んだ後:
master="path/masterlist.txt"
while read json_path; do
while read key; do
printf 'File="%s", Key="%s"\n' "$json_path" "$key"
jq ". .'$key'" "$json_path"
done <key.txt
done <"$master" >list.txt
JSONファイルのリストを読み、$master
各パスを順番に割り当てます。json_path
key.txt
内部ループはキーを順番に読み取り、割り当てますkey
。ユーティリティは、jq
現在のキー値に拡張された引数を使用して呼び出されます。$json_path
. .'$key'
$key
すべての出力はに入力されますlist.txt
。
内部ループには若干の最適化が必要な場合があります。たとえば、外部ループを繰り返すたびにすべてのキーを読む必要はないようです。
コメント付きのスクリプトバージョン:
master="path/masterlist.txt" # this is never used
while read master # this will set $master to something from list.txt
do
for KEY in 'key.txt' # $KEY will be the string 'key.txt' (nothing else)
do
jq '. .'$KEY'' $f # $f is empty
echo $KEY
done >> list.txt # better to >list.txt after "done" of outer loop
echo $master
done < list.txt # you probably don't want to read from this file
答え2
$f
アップロードしたスクリプトを読んで、割り当てが間違っているようです。また、コマンド内の参照によってjq
問題が発生する可能性があります。実際、whileループから単語を読み取ろうとしていますが、ループ内に単語を追加しようとすることmaster
もできます。list.txt
list.txt
#!/bin/bash
master="path/masterlist.txt"
cat $master | while read f; do
for KEY in 'key.txt'; do
echo $(jq ". .'$KEY'" $f) >> list.txt
done
echo $master
done
次に、ファイルから各行を取得し、$master
ループ内の変数に割り当て、クエリを実行して出力を 。$f
jq
list.txt