#json #jq
#json #jq
Вопрос:
команда:
cat test.json | jq -r '.[] | select(.input[] | .["$link"] | contains("randomtext1")) | .id'
Я ожидал, что будут отображаться обе записи ( a
и b
), поскольку они обе содержат randomtext1
Вместо этого я получил следующее выходное сообщение:
a
jq: error (at <stdin>:22): Cannot index string with string "$link"
Из некоторого анализа я понимаю, что проблема, вероятно, вызвана следующей парой объект / значение в a
записи:
"someotherobj": "123"
поскольку он не содержит объект $link
, и фильтр в команде ожидает увидеть $link
во всех объектах под input
so, он выдает ошибку, прежде чем команда получит возможность выполнить поиск в b
записи.
Чего я действительно хочу, так это иметь возможность искать любые записи, в которых есть хотя бы одна "$link": "randomtext1"
пара input
. Есть ли более нечеткая функция поиска, позволяющая мне достичь этого?
Я попытался использовать два contains
, надеясь, что он просто пропустит все:
jq -r '.[] | select(.input[] | contains(["$link"]) | contains("randomtext1")) | .id'
но это совсем не понравилось..
файл test.json:
[
{
"input": {
"obj1": {
"$link": "randomtext1"
},
"obj2": {
"$link": "randomtext2"
},
"someotherobj": "123"
},
"id": "a"
},
{
"input": {
"obj3": {
"$link": "randomtext1"
},
"obj4": {
"$link": "randomtext2"
}
},
"id": "b"
}
]
Ответ №1:
Чего я действительно хочу, так это иметь возможность искать любые записи, которые имеют хотя бы одну пару «$link»: «randomtext1» при вводе.
Ключевым словом здесь, как в вопросе, так и в следующем ответе, является any
:
.[]
| select( any(.input[];
type=="object" and has("$link") and (.["$link"] | index("randomtext1"))))
| .id
Конечно, если вам требуется, чтобы значение ключа было «randomtext1», вы бы написали .["$link"] == "randomtext1"
.
Комментарии:
1. Спасибо @peak. Команда хорошо работает с примером:
cat test.json | jq -r '.[] | select( any(.input[]; has("$link") and (.["$link"] | index("randomtext1") ) ) ) | .id'
я не знаю, есть ли какой-то механизм кэширования или мой компьютер. Если я изменю значения в test.txt файл, для целей тестирования, возникает несогласованная ошибка «Не удается проверить, имеет ли строка строковый ключ»:change both "randomtext1" to "randomtext3"
2. … или
change the first "randomtext1" to "randomtext3"
.3. Та же проблема с
select( any(.input[]; has("$link") and (.["$link"]=="randomtext1" ) ) )
тем, что кажется, что команда просто выдает ошибку при первом вводе, если она не соответствует критериям фильтра. Я хочу, чтобы она отображала запись, содержащую текст randomtext1, и игнорировала любую запись, которая этого не делает.4. Соответствует ли обновленный ответ, который проверяет type==»object», вашим требованиям?
5. да!
cat test.json | jq -r '.[] | select( any(.input[]; type=="object" and has("$link") and (.["$link"]=="randomtext1"))) | .id'
Спасибо!