Другое

Как парсить JSON данные из curl с помощью Unix инструментов

Узнайте несколько методов парсинга JSON данных из ответов curl с помощью Unix инструментов, таких как sed, awk и jq. Эффективно извлекайте конкретные поля с практическими примерами и фрагментами кода.

Как разобрать JSON-данные из curl-запроса с помощью Unix-инструментов и извлечь определенные поля?

Я пытаюсь разобрать JSON, возвращаемый curl-запросом, с помощью следующей команды:

bash
curl 'http://twitter.com/users/username.json' |
    sed -e 's/[{}]/''/g' | 
    awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}'

Приведенная выше команда разбивает JSON на отдельные поля, выдавая вывод, похожий на:

% ...
"geo_enabled":false
"friends_count":245
"profile_text_color":"000000"
"status":"in_reply_to_screen_name":null
"source":"web"
"truncated":false
"text":"My status"
"favorited":false
% ...

Как можно изменить эту команду, чтобы выводить только определенное поле, например, поле ‘text’, указанное параметром -v k=text в команде awk?

Парсинг JSON данных из curl и извлечение конкретных полей с помощью Unix-инструментов

Для парсинга JSON данных из curl-запроса и извлечения конкретных полей с помощью Unix-инструментов можно модифицировать существующую команду awk или использовать более надежные альтернативы. Ключевым моментом является добавление логики фильтрации в ваш awk-скрипт для вывода только полей, соответствующих указанному ключу.

Вот несколько подходов к извлечению конкретных полей JSON:


Содержание


Улучшение вашей текущей команды awk

Чтобы модифицировать вашу существующую команду для вывода только поля ‘text’, необходимо добавить соответствие шаблонов в awk:

bash
curl 'http://twitter.com/users/username.json' |
    sed -e 's/[{}]/''/g' | 
    awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) if (a[i] ~ "\""k"\":") print a[i]}'

Эта улучшенная версия:

  • Сохраняет существующую структуру парсинга JSON
  • Добавляет условие if для проверки, содержит ли каждое поле указанный ключ
  • Использует соответствие регулярных выражений для поиска полей с именем ключа

Для более чистого вывода можно дополнительно улучшить ее:

bash
curl 'http://twitter.com/users/username.json' |
    sed -e 's/[{}]/''/g' | 
    awk -v k="text" -F':' '{for(i=1;i<=NF;i+=2) if ($i ~ "\""k"\"") print $(i+1)}' |
    sed 's/"//g'

Использование sed для простого извлечения полей

Более простой подход на основе sed может извлекать конкретные поля с использованием шаблонов регулярных выражений:

bash
curl 'http://twitter.com/users/username.json' | sed -n 's/.*"text":"\([^"]*\)".*/\1/p'

Эта команда:

  • Использует команду подстановки sed с захватывающими группами
  • Соответствует шаблону "text":"значение" и извлекает только значение
  • Флаг -n подавляет автоматический вывод
  • \1 ссылается на первую захватывающую группу (значение поля)

Для более сложного вложенного JSON могут потребоваться несколько команд sed или более сложные шаблоны.


Рекомендуемое решение с jq

Наиболее надежным и поддерживаемым подходом является использование jq - специализированного процессора JSON:

bash
curl 'http://twitter.com/users/username.json' | jq -r '.text'

Эта команда:

  • Флаг -r выводит сырые строки (удаляет кавычки)
  • Прямо обращается к полю text с использованием нотации пути JSON
  • Надежно обрабатывает вложенные структуры, массивы и сложный JSON
  • Значительно более читаема и поддерживаема, чем сложные комбинации sed/awk

Для установки jq в большинстве систем:

bash
# Ubuntu/Debian
sudo apt-get install jq

# CentOS/RHEL
sudo yum install jq

# macOS
brew install jq

Альтернатива Python для сложного JSON

Когда jq недоступен, встроенный модуль JSON Python обеспечивает надежный парсинг:

bash
curl 'http://twitter.com/users/username.json' | python -c "import sys, json; data=json.load(sys.stdin); print(data['text'])"

Этот подход:

  • Использует стандартный парсер JSON Python для точного парсинга
  • Обрабатывает всю корректную синтаксис JSON включая экранированные символы
  • Работает в большинстве систем с установленным Python
  • Может быть расширен для сложной обработки данных

Продвинутые техники awk

Для более сложного парсинга JSON с awk можно использовать эти шаблоны:

Извлечение вложенных полей:

bash
curl 'http://api.example.com/data' | awk -F'"' '/"text"/{print $4}'

Более надежное извлечение полей:

bash
curl 'http://api.example.com/data' | awk -F'[":,]' '
    BEGIN{k="text"}
    $0 ~ k {for(i=1;i<=NF;i++) if($i==k) print $(i+1)}
'

Обработка массивов и вложенных структур:

bash
curl 'http://api.example.com/data' | awk -v k="text" -F'[":,]' '
    $0 ~ k {
        for(i=1;i<=NF;i++) {
            if($i==k) {
                val=$(i+1)
                gsub(/[^a-zA-Z0-9._-]/,"",val)
                print val
                exit
            }
        }
    }
'

Сравнение разных подходов

Метод Плюсы Минусы Лучше всего подходит для
jq Наиболее надежный, читаемый, обрабатывает весь синтаксис JSON Требует установки Производственные скрипты, сложный JSON
Python Надежный парсинг, обработка граничных случаев Медленнее, требует Python Сложная обработка, запасной вариант
sed Просто для базовых случаев Хрупкий при сложном JSON Быстрые однострочники, простое извлечение
awk Не требует установки в большинстве систем Сложный для вложенных структур Существующие рабочие процессы на awk
Исходная команда Знакомый синтаксис Неэффективный, хрупкий Изучение концепций парсинга JSON

Практические примеры и случаи использования

Извлечение нескольких полей с jq:

bash
curl 'http://api.example.com/user' | jq -r '.name, .email, .created_at'

Условное извлечение с jq:

bash
curl 'http://api.example.com/data' | jq -r '.items[] | select(.active == true) | .text'

Обработка ошибок в bash-скриптах:

bash
#!/bin/bash
response=$(curl -s 'http://api.example.com/data')
if [ $? -eq 0 ]; then
    text=$(echo "$response" | jq -r '.text // "Текст недоступен"')
    echo "Текст: $text"
else
    echo "Не удалось получить данные"
fi

Обработка ответов API в циклах:

bash
for id in 1 2 3; do
    curl "http://api.example.com/users/$id" | jq -r '.name'
done

Наиболее надежное решение для производственного использования - jq, в то время как улучшенная команда awk хорошо работает для простых случаев, когда дополнительные инструменты недоступны. Всегда учитывайте сложность ваших JSON-данных и поддерживаемость решения при выборе подхода.

Источники

  1. Unix Stack Exchange - How to extract certain value from curl JSON output
  2. Stack Overflow - Parsing JSON with Unix tools
  3. Unix Stack Exchange - Extract value from JSON document returned by curl
  4. Stack Overflow - Getting JSON value from cURL in Linux Bash
  5. Medium - Parse JSON data using jq and curl from command line
  6. Raymii.org - Get a JSON value with bash and sed
  7. Stack Overflow - Extract values from a Json in bash
  8. Unix Stack Exchange - How to retrieve values from json object using awk or sed

Заключение

Для парсинга JSON данных из curl и извлечения конкретных полей:

  1. Для надежных решений: Используйте jq -r '.field_name' - это наиболее надежный и читаемый подход
  2. Для быстрых однострочников: Используйте sed с шаблонами регулярных выражений, такими как sed -n 's/.*"field":"\([^"]*\)".*/\1/p'
  3. Для существующих рабочих процессов awk: Модифицируйте вашу текущую команду с соответствием шаблонов для фильтрации по имени поля
  4. Для сложной обработки: Рассмотрите модуль json Python, когда jq недоступен
  5. Для производственных скриптов: Всегда обрабатывайте ошибки и граничные случаи в вашей логике парсинга JSON

Главный вывод заключается в том, что хотя Unix-инструменты вроде sed и awk могут парсить JSON, они хрупки при работе со сложными структурами. Для серьезной работы jq стоит установить и изучить, так как он правильно обрабатывает весь синтаксис JSON и делает ваш код гораздо более поддерживаемым.

Авторы
Проверено модерацией
Модерация