Regex с командой sed для разбора текста json

С хоста, если вы правильно настроили ssh, вы можете

sshfs <username>@<containerMachine> 'mkdir /container/directory/to/mount/host/dir ; sshfs -o idmap=user <username>@<hostMachine>:/host/dir/to/share /container/directory/to/mount/host/dir ; '

Это временное монтирование, которое исчезнет при следующей перезагрузке.

1
задан 23 December 2016 в 18:29

6 ответов

Работа для jq:

jq -r '.["buildStatus"]["status"]' file.json

Может быть сокращена до:

jq -r '.buildStatus.status' file.json

-r (--raw-output) выводит строку без строки json

Пример:

% cat file.json                   
{
    "buildStatus" : {
        "status" : "ERROR",
        "conditions" : [{
                "status" : "OK",
                "metricKey" : "bugs"
            }, {
                "status" : "ERROR",
                "metricKey" : "test_success_density"
            }, {
                "status" : "OK",
                "metricKey" : "vulnerabilities"
            }
        ],
        "periods" : []
    }
}

% jq -r '.["buildStatus"]["status"]' file.json
ERROR

% jq -r '.buildStatus.status' file.json       
ERROR

Если он еще не установлен, установите его (доступно в репозитории Universe): [!d6 ]

sudo apt-get install jq 
9
ответ дан 23 May 2018 в 03:05

Как уже упоминалось, синтаксический анализ сложных структурированных данных является предпочтительным с соответствующим API. Python имеет модуль json для этого, который я лично использую довольно много в своих сценариях, и довольно легко извлечь нужные вам поля так:

$ python -c 'import sys,json;print json.load(sys.stdin)["buildStatus"]["status"]' <  input.txt
ERROR

Что происходит здесь, так это то, что мы перенаправить входной файл на stdin python и прочитать это с помощью json.load(). Это становится словарем python с ключом «buildStatus», и он содержит другой словарь python с ключом «статус». Таким образом, мы просто печатаем значение ключа в словаре, который хранится в другом словаре. Довольно просто.

Помимо простоты, еще одно преимущество заключается в том, что python и этот API все предустановлены и поставляются с Ubuntu по умолчанию.

9
ответ дан 23 May 2018 в 03:05

Вы действительно можете сделать это в sed, но я настоятельно рекомендую вам использовать более сложный язык, на котором есть инструменты, написанные для обработки данных JSON. Например, вы можете попробовать perl или python.

Теперь, в вашем простом примере, все, что вам нужно, это первое появление "status", поэтому вы можете сделать:

$ sed -nE '/status/{s/.*:\s*"(.*)",/\1/p;q}' file.json 
ERROR

Фокус в том, чтобы использовать -n для избегайте печати, а затем, если строка соответствует status (/status/), вы удаляете все, кроме части, которую вы хотите s/.*:\s*"(.*)",/\1/, p выровняйте линию и q uit.

Лично я считаю эту эквивалентную команду grep намного проще:

$ grep -m1 -oP '"status"\s*:\s*"\K[^"]+' file.json 
ERROR

Или этот:

$ perl -ne 'if(s/.*"status"\s*:\s*"([^"]+).*/$1/){print;exit}' file.json 
ERROR

Серьезно хотя, если вы планируете разбирать файлы JSON, не пытайтесь делать это вручную. Используйте подходящий парсер JSON.

6
ответ дан 23 May 2018 в 03:05
  • 1
    или этот: grep -m 1 status file.json | tr -cd '[[:alnum:]]:' | cut -f2 -d':' – siloko 23 December 2016 в 17:37
  • 2
    @ user1876040 добро пожаловать. Пожалуйста, не забудьте принять один из ответов (я рекомендую ByteCommander , его лучшее решение), поэтому вопрос может быть отмечен как ответ). – terdon♦ 23 December 2016 в 17:45

Не говори, что вы должны использовать sed (я думаю, что кто-то отказал мне в этом, просто за то, что я не написал обязательную оговорку), но если вам нужно найти что-то на следующей строке buildStatus, как вы, кажется, пытаетесь в своем Собственная попытка, вы должны сказать sed, чтобы прочитать следующую строку с командой N

$ sed -rn '/buildStatus/N;s/.*buildStatus.*\n.*: "(.*)",/\1/p' file
ERROR

Примечания:

-n ничего не печатают, пока мы попросите его -r использовать ERE (так же, как -E) /buildStatus/N найти этот шаблон и прочитать следующую строку слишком s/old/new/ заменить old на new .* любое количество любых символов в строке [ f14] newline : "(.*)", сохранить любые символы, возникающие между : " и ", \1 назад ссылкой на сохраненный паттерн p распечатать часть, над которой мы работали
4
ответ дан 23 May 2018 в 03:05

Существует типичное объяснение того, почему инструменты sed и аналогичные средства обработки текстовых потоков не очень хорошо разбираются в структурированных данных, таких как JSON и XML. У меня нет этого, но он есть, и я считаю, что суть в том, что выражения, необходимые во всех, но, вероятно, в немногих ситуациях, быстро становятся очень сложными, в то время как альтернативные инструменты, созданные специально для синтаксического анализа структуры, элегантный, читаемый и эффективный при одном и том же разборе.

Как и муру, комментарий jq должен быть правильным инструментом для задания. Я также могу ручаться за то, что он очень рад видеть, как он несколько раз заменяет меня, когда я пробовал разобрать одни и те же данные, чтобы не получить почти никакого или обременительного успеха. Он даже содержит большое количество возможностей для форматирования и управления данными. Я предпочитаю его jsontool по той или иной причине, которую я сейчас забываю.

muru , кажется, рекомендует jshon в другом ответе. Я не использовал этот инструмент, но он напоминает мне xmlstarlet и его синтаксис, а также некоторые настраиваемые представления для вывода.

0
ответ дан 23 May 2018 в 03:05
  • 1
    Вероятно, вы говорите о stackoverflow.com/a/1732454/2072269 – muru 23 December 2016 в 21:34
  • 2
    Попробуйте улучшить свой ответ, показывая пример того, как jsontool можно использовать для конкретного случая OP – Sergiy Kolodyazhnyy 23 December 2016 в 22:06
  • 3
    Lol @muru, правильно, это одно из сообщений, пытающихся удержать использование от разбора XML / JSON с Regex! Я больше советовал jq, что муру и гемейл описывают, что уже имеют примеры, и просто публикуют аргументы позади этого: askubuntu.com/a/863948/230721 – Pysis 26 December 2016 в 23:19

Просто еще один инструмент Json под названием json (https://github.com/trentm/json)

$ json buildStatus.status < file.json
ERROR

Это примерное исследование вводит в заблуждение: похоже, что инструменты не работают. Вы также можете использовать json для изменения json-файлов:

$ json -e 'this.buildStatus.status="not error"' < file.json > new.json

или даже ...

$ json -e 'this.buildStatus.status="no errors"' < file.json | json -e 'this.buildStatus.status
no errors

документация в: https://github.com / trentm / json

если не установлено:

установить узел и sudo npm install -g json
0
ответ дан 23 May 2018 в 03:05

Другие вопросы по тегам:

Похожие вопросы: