私は次のStackexchange記事のアイデアに従いました。
しかし、選択して追加すると、引用符に問題があります。
私のサンプルjsonファイルは次のとおりです。
{
"options": [
{
"label": "22",
"value": "2022"
},
{
"label": "23",
"value": "2023"
}
]
}
これは私のテストbashスクリプトです。
#!/bin/bash
previous_year=$(date --date="$(date +'%Y') - 1 year" +%Y)
last_year=$((previous_year + 31))
label=$((last_year -2000))
echo ${last_year}
jq 'del(.options[]? | select(.label == \"${previous_year}\"))' temp.json
jq '.options += [{
"label": '${label}',
"value": '${last_year}'
}]' temp.json
このサンプルファイルを使用して bash スクリプトを実行すると、jq: error: Syntax error, Unexpected INVALID_CHARACTER (Unix shell quoteing issue?) at , line 1: del(.options[]? | select(.label == "$)発生します。{前の年}})
jq:1コンパイルエラー
「を削除すると実行されますが、引用符がないように見えるため、削除する項目が見つかりません。また、要素を配列に追加しますが、引用符は追加しません。
どうすればいいですか?
- 引用符で要素を検索
- 引用された要素の追加
予想される結果(私が達成したいもの)は次のとおりです。
{
"options": [
{
"label": "23",
"value": "2023"
},
{
"label": "53",
"value": "2053"
}
]
}
答え1
label
シェル変数に正しい値があり、その値を持つ配列内のすべての項目を削除し、last_year
その値と値を持つ新しい項目を追加するとします。previous_year
options
value
$previous_year
label
$label
value
$last_year
jq --arg add_label "$label" \
--arg add_value "$last_year" \
--arg del_value "$previous_year" '
del(.options[]? | select(.value == $del_value)) |
.options += [{ label: $add_label, value: $add_value }]' file
これにより、1回の呼び出しで2つの操作が正しく結合されますjq
。
このコマンドは、jq
以前に作成したシェル変数から取得した値を使用して、3つの内部文字列変数をインスタンス化します。--arg
シェル変数で生成された内部文字列変数を使用すると、値が正しくエンコードされるようになります(これによりコード挿入の脆弱性を防ぐことができます)。
コードと同様に、配列が存在しない場合はエラーを回避する.options[]?
ために代わりに使用します。存在する場合、値が(シェル変数の値を持つ内部変数)の項目は削除されます。 selectを使ってみましたが、私はタイプミスかもしれないと思います。.options[]
options
value
$del_value
previous_year
label
(おそらく)変更された文書は次のステップに渡され、配列に新しい要素が追加されますoptions
。配列が以前に存在しなかった場合は、単一要素として生成されます。
また、jq
内部編集は行われないため、上記のコマンドの出力を新しい名前にリダイレクトしてから、元のファイルをその新しいファイルに置き換える必要があることを意味します。またはGNUを使用してくださいsponge
。
jq ...as above... file | sponge file
(ファイル名はと仮定しますfile
。)
答え2
#!/bin/bash
file=temp.json
now="$(date)"
previous_year=$(date --date="$(date +'%Y') - 1 year" +%Y)
last_year=$((previous_year + 31))
label=$((last_year -2000))
echo "==============================================================================================================="
echo "| Started parsing json file at script at: $file"
echo "| Started at: $now"
echo "| previous year is: $previous_year"
echo "| last year to be at json array is: $last_year"
echo "| label assigned to the last year : $label"
echo "==============================================================================================================="
if cat $file | grep $previous_year
then
jq --arg key "$previous_year" 'del(.options[] | select(.value == $key))' $file >> new.json
jq --arg key "$label" --arg val "$last_year" '.options += [{
"label": $key,
"value": $val
}]' new.json >> new2.json
mv new2.json $file
rm new.json
echo "last year found and parsed"
else
echo "nothing to be done"
fi
now="$(date)"
echo "==============================================================================================================="
echo "| Ended script at: $now"
echo "==============================================================================================================="
´´´