Вопрос или проблема
Я использую bash-скрипт, который должен читать JSON-вывод и извлекать значения из разных JSON-переменных или строк. Вот пример вывода. Необходимо извлечь значение рядом с Content
или из любой другой переменной. Например,
Найти Content
и иметь возможность вывести Value1
.
Найти DeviceType
и иметь возможность вывести Value4
Пример вывода:
{"Content":"Value1","CreationMethod":"Value2","database":"Value3","DeviceType":"Value4"}
Я пробовал комбинацию sed и awk sed 's/["]/ /g' | awk '{print $4}'
, но только если позиция Content
остается такой же в выводе. В противном случае в другом JSON-выводе позиция Content
меняется, что выводит значение за пределы области действия, поэтому awk '{print $4}'
берет неправильное значение.
jq
меньше и perl
меньше кувалда, используя предполагаемый OP sed
/awk
s="Content"; sed 's/[{}"]//g' file | awk -v s=$s -F ":" -v RS=',' '($1 == s) {print $2}'
Хорошо, я признаю, что это ужасно…
$ awk 'BEGIN {FPAT="\"[^\"]+\""; RS=","; pat=ARGV[1]; delete ARGV[1]}
$1 ~ pat {print $2} ' Content ex.json
"Value1"
$ jq -r '.Content' file
Value1
$ jq -r '.DeviceType' file
Value4
Нет причин не устанавливать jq
для правильного, безопасного разбора JSON и без необходимости вручную декодировать JSON-кодированные строки и т. д.
Утилита jq
доступна для скачивания в форме, не требующей прав root для установки в вашем домашнем каталоге (нет внешних зависимостей времени выполнения).
Ответ или решение
Чтобы правильно извлечь значения из строк JSON в Bash, не прибегая к утилите jq
, мы можем использовать комбинацию команд sed
и awk
для обработки строк. Этот подход может быть полезен в ситуациях, когда установка дополнительных инструментов невозможна или нежелательна.
Проблема
У вас есть строка JSON, например:
{"Content":"Value1","CreationMethod":"Value2","database":"Value3","DeviceType":"Value4"}
Вам нужно извлечь значение, связанное с Content
, и значение, связанное с DeviceType
, независимо от их положения в строке.
Решение
Вы можете использовать следующее решение с sed
и awk
:
- Извлечение значений с помощью
sed
иawk
json='{"Content":"Value1","CreationMethod":"Value2","database":"Value3","DeviceType":"Value4"}'
# Укажите ключ, который вы хотите найти
key="Content"
# Извлечь значение по ключу
value=$(echo "$json" | sed 's/[{}"]//g' | awk -v key="$key" -F ":" '{ for (i=1; i<=NF; i+=2) if ($i == key) print $(i+1) }')
echo "Значение Content: $value"
# Повторить для DeviceType
key="DeviceType"
value=$(echo "$json" | sed 's/[{}"]//g' | awk -v key="$key" -F ":" '{ for (i=1; i<=NF; i+=2) if ($i == key) print $(i+1) }')
echo "Значение DeviceType: $value"
Объяснение
- Команда
sed
: Убирает фигурные скобки и кавычки из строки JSON, оставляя только чистые пары ключ-значение. - Команда
awk
:- Мы используем опцию
-F ":"
, чтобы указать, что разделителем полей будет двоеточие. - Цикл перебирает все поля; если ключ совпадает с искомым ключом, значением будет значение, находящееся сразу после ключа.
- Мы используем опцию
Преимущества данного подхода
- Не требуют внешних утилит: Вы можете использовать только стандартные инструменты, интегрированные в Bash.
- Гибкость: Подход может быть адаптирован для извлечения любых значений из строки JSON.
Недостатки
- Уязвимость к ошибкам в JSON-формате: Если JSON строка будет неправильно сформирована, скрипт может не работать должным образом.
- Отсутствие проверки формата: Нет проверки на наличие ключа, а также более глубокой структуры вложенных объектов.
Заключение
Использование комбинации команд sed
и awk
позволяет избежать установки jq
для извлечения значений из строк JSON. Хотя это может быть менее безопасно и надежно, чем использование специализированного инструмента, данный метод работает для простых случаев и может быть легко реализован в скриптах Bash. Надеемся, что предложенное решение будет полезным в вашей ситуации.