Фильтрация массива JSON объектов с использованием условия тестирования регулярных выражений - PullRequest
1 голос
/ 06 апреля 2020

Мне часто отправляют мне файлы HAR (которые JSON), которые выглядят так:

{
    "log": {
        "entries" : [
            {
                "request" : {
                    "url" : "test.css"
                }
            },
            {
                "request" : {
                    "url" : "test.ok"
                }
            },
            {
                "request" : {
                    "url" : "test.font"
                }
            },
            {
                "request" : {
                    "url" : "ok"
                }
            }
        ]
    }
}

Меня не волнуют запросы, содержащие URL-адреса для шрифтов, CSS, или JavaScript. Итак, я хотел бы удалить эти запросы, используя jq. Учитывая ответ от @ iain-samuel-mclean-elder о фильтрации и поддержании структуры JSON входных данных, я ожидал, что что-то подобное сработает:

jq '[ .[] | select(.log.entries[].request.url | test("\\.(js|css|font)") | not) ]' < MyGoodHarFile.json

Это, однако, приводит к ошибке:

jq: error (at <stdin>:25): Cannot iterate over null (null)

Что я делаю не так? Как я могу создать действительный файл HAR, исключая запросы на эти определенные соответствующие URL-адреса, используя jq?

1 Ответ

3 голосов
/ 06 апреля 2020

Вы должны быть очень осторожны, где и как используются операторы select. Предотвращение ошибки неверного родительского пути .[] в исходном фильтре

[select(.log.entries[].request.url | test("\\.(js|css|font)") | not)] 

приведет к получению всего ввода дважды, поскольку фильтр утверждает true для двух ваших объектов, поскольку select() реплицирует весь ввод на true условие.

Благодаря выполнению .log.entries|= ваш ввод теперь выполняется только для массива объектов, которые при утверждении true через регулярное выражение сохраняются, а остальные исключаются.

jq '.log.entries |= ( map ( select ( .request.url | test("\\.(js|css|font)") |not ) ) )'
...