(Терминал Mac) sed для парсинга JSON …, что я делаю неправильно?

возможно один путь состоит в том, чтобы обновить для бормотания 3.0

Чтобы сделать это, сначала необходимо добавить debian экспериментальные репозитории. Откройте/etc/apt/sources.list как su и добавьте

# Experimental (just when explicitly demanded)
deb http://ftp.at.debian.org/debian/ experimental main contrib non-free
deb-src http://ftp.at.debian.org/debian/ experimental main contrib non-free

Следующий шаг очень важен. Откройте/etc/apt/apt.conf как su и удостоверьтесь, что он содержит эту строку

APT::Default-Release ""; # (your release could be "testing" for example)

При пропавших без вести этого шага система, вероятно, изменилась бы на экспериментальный debian.

Теперь обновите свою информацию о хранилище

apt-get update

и установка бормочет от экспериментального

apt-get -t experimental install mutter

На моем ноутбуке экспериментальное бормотание не вызвало проблем до сих пор...

Возможно, также требуется считать раздел 3.8 из этого документа перед внесением тонких изменений в системе.

4
28.08.2012, 11:08
5 ответов

Это - выражение, которое Вы ищете:

sed -e 's/^.*"name":"\([^"]*\)".*$/\1/' infile

Это заканчивается к:

CastingBy-v12 mixed.mov

В Вашем существует несколько ошибок:

  • В sed только выражение greeding может использоваться: .*? и .+? являются неправильными.
  • + должен быть оставлен.
  • Использовать [^"]* избегать что соответствия регулярного выражения до последних двойных кавычек строки.
7
27.01.2020, 20:44
  • 1
    Спасибо за все подсказки! Но это все еще возвращает всю строку. Я использую echo "{my big string}" | sed 's/^.*"name":"\([^"]\+\)".*$/\1/' –  Dan 28.08.2012, 00:53
  • 2
    @Ze'ev:Прошу прощения. это работает на меня, и я не могу поймать проблему, которая не работает на Вас. –  Birei 28.08.2012, 01:03
  • 3
    Возможно, потому что я нахожусь на Mac с помощью Терминала? –  Dan 28.08.2012, 01:14
  • 4
    @zeev, Да, Mac использует BSD sed, который не имеет всех функций гну. Я протестировал немного, и кажется, что sed Mac не распознает также + или \+. Изменение это к * . –  Kevin 28.08.2012, 02:24
  • 5
    @Kevin АГА! Это сделало это!Спасибо! | sed 's/^.*"name":"\([^"]*\)".*$/\1/' –  Dan 28.08.2012, 06:29

Парсинг json только с sed так же проблематичен как парсинг HTML - короче говоря: так как элементы могут встроить другие элементы, и regex не поддерживает рекурсию, чрезвычайно невозможно проанализировать правильно только с regexp.

Существует решение PCRE парсинга и проверки json здесь: https://stackoverflow.com/questions/2583472/regex-to-validate-json - я не использовал или протестировал его так, я должен буду взять слово автора, что это работает..., но PCRE делает много вещей, которые просто не находятся в основном или расширенном regexps, поддерживаемом sed.

В любом случае IMO, Вы - более обеспеченный жемчуг использования или Python или awk и один из парсинга json, освобождает для тех языков или специализированного json парсинг инструмента - несколько упоминаются здесь:

https://stackoverflow.com/questions/3858671/unix-command-line-json-parser

Любой из них может использоваться для извлечения данных из входа JSON для использования в сценарии оболочки. Или Вы могли записать свою всю программу в том языке.

Например, передавая Ваши json данные по каналу в Python-mjson.tool приводит к этому:

$ echo "JSONDATAHERE" | python -m json.tool
{
    "content_url": "http://files.eeehousenyc.com/1I3Q0Z1E2F3C/CastingBy-v12%20mixed.mov", 
    "created_at": "2012-08-27T20:04:27Z", 
    "deleted_at": null, 
    "download_url": "http://files.eeehousenyc.com/1I3Q0F3C/download/CastingBy-v12%20mixed.mov", 
    "gauge_id": null, 
    "href": "http://my.cl.ly/items/2840", 
    "icon": "http://my.cld.me/images/item-types/video.png", 
    "id": 21462840, 
    "item_type": "video", 
    "name": "CastingBy-v12 mixed.mov", 
    "private": true, 
    "redirect_url": null, 
    "remote_url": "http://f.cl.ly/items/3D0P02b3e3p2I/CastingBy-v12%20mixed.mov", 
    "source": "Cloud/1.5.4 CFNetwork/520.4.3 Darwin/11.4.0 (x86_64) (MacPro5%2C1)", 
    "subscribed": true, 
    "updated_at": "2012-08-27T20:13:38Z", 
    "url": "http://files.housenyc.com/1I3E2F3C", 
    "view_counter": 2
}

который можно затем передать по каналу в sed как это:

$ echo "JSONDATAHERE" | python -m json.tool | sed -n -e '/"name":/ s/^.*"\(.*\)".*/\1/p'
CastingBy-v12 mixed.mov

Полагаясь на жадную природу regexp, sed сценарий извлекает все между предпоследним " и последнее " символ на любой строке, содержащей "name":.

10
27.01.2020, 20:44
  • 1
    BTW, да я использовал regexps для парсинга HTML и JSON. Я даже заставил его работать на мои определенные потребности в то время..., но я знаю, что то, что я сделал, было хрупко и подвержено отказу и очень чувствительно к входным данным. В эти дни я обычно нахожу это легче и намного более надежным, чтобы предварительно обработать json данные с python -m json.tool и затем канал, что в sed или awk. или просто пишут сценарий жемчуга с помощью модуля JSON. Я буду все еще использовать regexps для быстрого и грязного взлома остроты, но для чего-либо намеревался использоваться неоднократно, я сделаю это правильно. –  cas 28.08.2012, 01:21

Этот dosn't отвечает на Ваш вопрос непосредственно. Но если необходимо сделать такие вещи регулярно, рассмотрите использование общедоступного языка программирования как Perl, Python, Ruby.

В Ruby Ваше решение было бы:

some_command_that_emits_json | ruby -e "require 'rubygems';require 'json'; output=JSON.parse(STDIN.gets); puts output['name']"

3
27.01.2020, 20:44

Идя от этого потока, это добивается цели:

echo {json...foo} | awk -F=":" -v RS="," '$1~/"name"/ {print}' | sed 's/\"//g' | sed 's/name://'

2
27.01.2020, 20:44
  • 1
    Вы, вероятно, хотите RS="," стать RS=",|{|}"; в случае, если то, что Вы ищете, вначале или конец строки. –  A T 03.02.2014, 06:24

Вот один способ сделать это с JSON модуль perl:

 json_producing_process | perl -MJSON -lne 'print from_json($_)->{name}'
1
27.01.2020, 20:44

Теги

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