Передать переменную строковых значений Bash с разделителями-запятыми в фильтр jq arg

Я пытаюсь отфильтровать данные из файла 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"
    }
]

Весь смысл --arg заключается в том, чтобы передавать ваш контент в виде данных, чтобы его нельзя было неверно истолковать как код или синтаксис.

Charles Duffy 12.12.2020 00:40

... тогда как когда вы добавляете кавычки и запятые, это синтаксис.

Charles Duffy 12.12.2020 00:41

... если вы хотите передать список, то передайте фактический список - используйте --argjson и перепишите свой запрос, чтобы он работал с ним.

Charles Duffy 12.12.2020 00:42

(и не используйте -r, когда вы выводите JSON вместо необработанных строковых данных в качестве вывода).

Charles Duffy 12.12.2020 00:44

Добро пожаловать в SO, и спасибо за включение короткого, простого, автономного примера (MCVE)! Это упрощает задачу как для тех, кто отвечает сейчас, так и для будущих читателей, которые столкнутся с этим вопросом.

that other guy 12.12.2020 00:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
775
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

--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 разных способов сделать это.

Justin 12.12.2020 03:26

Другие вопросы по теме