Ответ 1
Для разбора json в командной строке jq
:
jq '.Body'
Посетите это для jq: https://stedolan.github.io/jq/
В оболочке у меня есть требование, в котором я должен прочитать ответ JSON, который находится в следующем формате:
{ "Messages": [ { "Body": "172.16.1.42|/home/480/1234/5-12-2013/1234.toSort", "ReceiptHandle": "uUk89DYFzt1VAHtMW2iz0VSiDcGHY+H6WtTgcTSgBiFbpFUg5lythf+wQdWluzCoBziie8BiS2GFQVoRjQQfOx3R5jUASxDz7SmoCI5bNPJkWqU8ola+OYBIYNuCP1fYweKl1BOFUF+o2g7xLSIEkrdvLDAhYvHzfPb4QNgOSuN1JGG1GcZehvW3Q/9jq3vjYVIFz3Ho7blCUuWYhGFrpsBn5HWoRYE5VF5Bxc/zO6dPT0n4wRAd3hUEqF3WWeTMlWyTJp1KoMyX7Z8IXH4hKURGjdBQ0PwlSDF2cBYkBUA=", "MD5OfBody": "53e90dc3fa8afa3452c671080569642e", "MessageId": "e93e9238-f9f8-4bf4-bf5b-9a0cae8a0ebc" } ] }
Здесь меня интересует только свойство свойства Body. Я сделал несколько неудачных попыток:
jsawk -a 'return this.Body'
или
awk -v k="Body" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}
Но этого было недостаточно. Может ли кто-нибудь помочь мне с этим?
Для разбора json в командной строке jq
:
jq '.Body'
Посетите это для jq: https://stedolan.github.io/jq/
$ cat /tmp/so.json | underscore select '.Messages .Body'
["172.16.1.42|/home/480/1234/5-12-2013/1234.toSort"]
Вы можете использовать инструменты Javascript CLI, например
Выберите всех name
дочерних элементов addons
:
underscore select ".addons > .name"
underscore-cli
предоставляют другие примеры реального мира, а также json: select() doc.
Аналогичным образом используется Bash regexp. Удалите любую пару ключ/значение.
key="Body"
re="\"($key)\": \"([^\"]*)\""
while read -r l; do
if [[ $l =~ $re ]]; then
name="${BASH_REMATCH[1]}"
value="${BASH_REMATCH[2]}"
echo "$name=$value"
else
echo "No match"
fi
done
Регулярное выражение может быть настроено на соответствие нескольким пробелам/вкладкам или символам новой строки. Не работает, если значение имеет встроенный "
. Это иллюстрация. Лучше использовать некоторый "промышленный" парсер:)
Вот грубый способ сделать это: преобразовать JSON в переменные bash
для их eval
.
Это работает только для:
Ну, да, он использует PERL для выполнения этой работы, благодаря CPAN, но достаточно мал для включения непосредственно в сценарий и, следовательно, быстро и легко отлаживается:
json2bash() {
perl -MJSON -0777 -n -E 'sub J {
my ($p,$v) = @_; my $r = ref $v;
if ($r eq "HASH") { J("${p}_$_", $v->{$_}) for keys %$v; }
elsif ($r eq "ARRAY") { $n = 0; J("$p"."[".$n++."]", $_) foreach @$v; }
else { $v =~ '"s/'/'\\\\''/g"'; $p =~ s/^([^[]*)\[([0-9]*)\](.+)$/$1$3\[$2\]/;
$p =~ tr/-/_/; $p =~ tr/A-Za-z0-9_[]//cd; say "$p='\''$v'\'';"; }
}; J("json", decode_json($_));'
}
используйте его как eval "$(json2bash <<<'{"a":["b","c"]}')"
Не сильно проверено, хотя. Обновления, предупреждения и другие примеры смотрите в моем GIST.
(К сожалению, ниже приведено решение только для ссылок, так как код C слишком длинный, чтобы его здесь дублировать.)
Для всех тех, кому не нравится вышеупомянутое решение, теперь есть программа на C json2sh, которая (надеюсь, безопасно) преобразует JSON в переменные оболочки. В отличие от фрагмента perl
, он способен обрабатывать любой JSON, если он правильно сформирован.
Предостережения:
json2sh
не был проверен много.json2sh
может создавать переменные, которые начинаются с шаблона shellshock () {
Я написал json2sh
для возможности .bson
Shell:
bson2json()
{
printf '[';
{ bsondump "$1"; echo "\"END$?\""; } | sed '/^{/s/$/,/';
echo ']';
};
bsons2json()
{
printf '{';
c='';
for a;
do
printf '%s"%q":' "$c" "$a";
c=',';
bson2json "$a";
done;
echo '}';
};
bsons2json */*.bson | json2sh | ..
Разъяснение:
bson2json
.bson
файл .bson
так, что записи становятся массивом JSON END0
-Marker, иначе вы увидите что-то вроде END1
.END
-Marker необходим, иначе пустые файлы .bson
не будут отображаться.bsons2json
выгружает кучу файлов .bson
как объект, где выходные данные bson2json
индексируются по имени файла. Затем он json2sh
, так что вы можете использовать grep
/source
/eval
/etc. что нужно, чтобы принести значения в оболочку.
Таким образом, вы можете быстро обработать содержимое дампа MongoDB на уровне оболочки, без необходимости сначала импортировать его в MongoDB.