ошибка выбора jq: «Невозможно индексировать строку с помощью string «

#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' Спасибо!