2017-01-31 8 views
0

Я использую API погоды, который выводит все данные в одной строке. Как использовать grep для получения значений для «summary» и «visibleTemperature»? Моя команда регулярных выражений в основном несуществует, но я готов учиться.Как grep из одной строки

{"latitude":59.433335,"longitude":24.750486,"timezone":"Europe/Tallinn","offset":2,"currently":{"time":1485880052,"summary":"Clear","icon":"clear-night","precipIntensity":0,"precipProbability":0,"temperature":0.76,"apparentTemperature":-3.34,"dewPoint":-0.13,"humidity":0.94,"windSpeed":3.99,"windBearing":262,"visibility":9.99,"cloudCover":0.11,"pressure":1017.72,"ozone":282.98}} 

Спасибо!

+1

Похоже JSON. Используйте инструмент JSON, а не регулярные выражения. – choroba

+0

Пожалуйста, добавьте желаемый результат для ввода этого образца в свой вопрос. – Cyrus

ответ

2

Как использовать grep для получения значений для «summary» и «visibleTemperature»?

Вы используете grep «s -o флаг, что делает вывод только соответствует части.

Поскольку вы мало знаете о регулярном выражении, я предлагаю вам научиться использовать парсер JSON, который будет более подходящим для этой задачи.

Например, с jq, следующая команда извлечет текущее резюме:

<whatever is your JSON source> | jq '.currently.summary' 
+0

Хорошо, jq отлично работает. Это простой сценарий bash, хотя я хотел бы поделиться с людьми, и для них было бы неудобно загружать пакет только для запуска скрипта. Не могли бы вы показать мне, как это сделать с регулярным выражением? – user1901162

+0

Если они просто хотят, чтобы выполнить сценарий, то я предполагаю, что регулярное выражение действительно будет более легко переносимым (хотя это спорно). Если они должны быть в состоянии поддерживать его, то независимо от того, насколько я люблю регулярные выражения, я бы рекомендовал «jq» :) edit: ранее я упомянул, что я бы добавил решение на основе регулярных выражений, но тот, который был предоставлен Фредом выглядит довольно хорошо – Aaron

+0

@ user1901162 На домашней странице 'jq' упоминается, что это переносимый единственный исполняемый файл (из 2.9Mo, я думаю), поэтому вы можете сделать tar или zip своего скрипта + jq, чтобы его распространить и предоставить инструкцию о том, как dezip + выполнить скрипт. Кроме того, вам не нужно беспокоиться о совместимости версии jq, так как вы упаковываете свой скрипт с проверенной версией jq. – Aaron

1

Предположим, что ваши данные одной строки содержится в переменной, которая называется DATA_LINE.

Если вы уверены, что поле присутствует только один раз во всей линии, вы могли бы сделать что-то подобное в Bash:

if 
    [[ "$DATA_LINE" =~ \"summary\":\"([^\"]*)\" ]] 
then 
    summary="${BASH_REMATCH[1]}" 
    echo "Summary field is : $summary" 
else 
    echo "Summary field not found" 
fi 

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

Как примечание, выражение соответствия \"summary\":\"([^\"]*)\" находит первое вхождение в данной подстроке, состоящее из:

  • «Резюме»:»(двойные кавычки включены), а затем
  • ([^ \ "] *) суб-выражение, сформированное из последовательности из нуля или более символов, отличных от двойной кавычки: это в скобках, чтобы сделать ее доступной позже как элемент в массиве BASH_REMATCH, потому что это значение, которое вы хотите извлечь
  • и, наконец, последняя цитата; это не совсем необходимо, но защищает от чтения из усеченной строки данных.

Для apparentTemperature код будет немного отличаться, потому что поле не имеет того же формата.

if 
    [[ "$DATA_LINE" =~ \"apparentTemperature\":([^,]*), ]] 
then 
    apparentTemperature="${BASH_REMATCH[1]}" 
    echo "Apparent temperature field is : $apparentTemperature" 
else 
    echo "Apparent temperature field not found" 
fi 
+0

Спасибо! Хотя немного неприятностей. Я могу получить резюме, чтобы показать, но не очевидная температура. Я сделал это дважды как для итоговой, так и для кажущейся температуры, но последнее не работает. – user1901162

+0

@ user1901162 Пожалуйста, см. Конец обновленного ответа. Вы должны изучить, как отличаются два шаблона регулярных выражений, и сравнить, как поля разделены в ваших данных, чтобы понять изменения. – Fred

+0

@ user1901162 Кстати, код, который я предложил, не имеет никакой зависимости, кроме Bash (этот код не совместим с POSIX). Внешняя команда не используется. – Fred

0

Это довольно легко понять, если ваши навыки ограничены - как и мои! Если предположить, что строка в переменной с именем $LINE:

summary=$(sed -e 's/.*summary":"//' -e 's/".*//' <<< $LINE) 

Затем проверьте:

echo $summary 
Clear 

, который выполняет (-e) 2 sed команды. Первый заменяет все до summary":" ничем, а второй заменяет первую оставшуюся двойную кавычку и все, что следует ни с чем.

экстракт кажущаяся температура:

appTemp=$(sed -e 's/.*apparentTemperature"://' -e 's/,.*//' <<< $LINE) 

Затем проверьте:

echo $appTemp 
-3.34