Я пытаюсь отфильтровать данные из файла json, используя jq с фильтром, основанным на динамическом списке значений из сценария Bash.
Следующая команда jq работает сама по себе:
jq -r '.[] | select(.name==("value1","value2"))' file.json
В Bash следующая команда работает, если я устанавливаю переменную в одно значение и передаю ее в
testValue = "value1"
result=$(jq -r --arg TESTVALUE "$testValue" '.[] | select(.name==($TESTVALUE))' file.json)
echo "$result"
Если я установлю переменную в список значений с разделителями-запятыми и передам ее, она не даст никаких результатов.
testValues = "\"value1\", \"value2\""
result=$(jq -r --arg TESTVALUES "$testValues" '.[] | select(.name==($TESTVALUES))' file.json)
echo "$result"
Я новичок в написании сценариев bash, поэтому я уверен, что мне не хватает чего-то простого в том, как интерпретируется переменная. Я также включил файл .json ниже.
[
{
"name": "value1",
"test": "blah1"
},
{
"name": "value2",
"test": "blah2"
}
]
... тогда как когда вы добавляете кавычки и запятые, это синтаксис.
... если вы хотите передать список, то передайте фактический список - используйте --argjson
и перепишите свой запрос, чтобы он работал с ним.
(и не используйте -r
, когда вы выводите JSON вместо необработанных строковых данных в качестве вывода).
Добро пожаловать в SO, и спасибо за включение короткого, простого, автономного примера (MCVE)! Это упрощает задачу как для тех, кто отвечает сейчас, так и для будущих читателей, которые столкнутся с этим вопросом.
--arg
будет рассматривать ваше значение как литеральную строку, поэтому кавычки и запятые не будут иметь никакого значения.
Вместо этого вы можете отформатировать свой список как действительный список JSON и использовать --argjson
:
testValues='[ "value1", "value2" ]'
jq --argjson TESTVALUES "$testValues" '.[] | select(.name==($TESTVALUES[]))' file.json
Или, возможно, даже лучше, укажите какой-нибудь разделитель и вместо этого jq разделите вашу строку, чтобы вам не пришлось беспокоиться об экранировании JSON:
testValues='value1,value2'
jq --arg TESTVALUES "$testValues" '.[] | select(.name==($TESTVALUES | split(",")[]))' file.json
Это сработало отлично! Спасибо за решение, а также за предоставление 2 разных способов сделать это.
Весь смысл
--arg
заключается в том, чтобы передавать ваш контент в виде данных, чтобы его нельзя было неверно истолковать как код или синтаксис.