Bash: вернуть все символы между n-ными вхождениями двух разных строк в строке

284
wdavro

В скрипте bash (в Ubuntu 14.04) я запускаю команду:

WP055="$(wget -qO - http://alerts.weather.gov/cap/wwaatmget.php?x=CAZ055&y=1)" 

В строке переменной WP055 будет неизвестное число пар «<title>» и «</ title>». Мне нужно искать в каждой из этих пар строку «по NWS», что означает, что эта конкретная строка содержит время начала и окончания конкретной информации о погоде. Эта найденная строка (все символы между открывающим и закрывающим тегами заголовка) - это то, что я хочу записать в другую переменную, чтобы я мог перетащить ее в файл index.html, который создает скрипт.

Я планировал перебирать переменную WP055 x количество раз, анализируя текст в каждой паре тегов, пока не найду правильный.

Я не могу найти WP055 для «по NWS», потому что в WP055 может быть более одного вхождения (несколько рекомендаций в строке WP055).

(У приведенной выше команды wget определенно будет строка 'by NWS' во 2-й паре заголовков до 07 марта в 3:00 по тихоокеанскому времени, когда текущее уведомление о ветре будет отменено.)

1
Вот это да. Большое спасибо @ G-Man. Я боролся с этим и строковыми индексами в течение двух полных выходных (и провалился). Ваше решение намного чище. Я включу это в свою программу поздно вечером и на следующих выходных. Благодарю. wdavro 8 лет назад 0
Пожалуйста. Просто чтобы вы знали, система уведомила меня о том, что вы приняли мой ответ, но не предупредила меня о вашем комментарии (см. Выше), даже если вы сказали «@ G-Man». Вы можете «пинговать» человека таким образом, только если вы прокомментируете сообщение, которое он написал, или под одним из его комментариев. Итак, если вы хотите что-то сказать кому-то, кто ответил на ваш вопрос, вы должны прокомментировать ответ. G-Man 8 лет назад 0

1 ответ на вопрос

0
G-Man

Немного неполированный, но, похоже, работает:

WP055="$(wget -qO - http://alerts.weather.gov/cap/wwaatmget.php?x=CAZ055&y=1)" remainder=$ if [ "$WP055" = "$remainder" ] then echo "No title found" exit fi while true do this_title=$ if [ "$remainder" = "$this_title" ] then echo "</title> not found" exit fi if [[ "$this_title" == *"by NWS"* ]] then echo "$this_title contains \"by NWS\"" # You probably want to do something here, like return. fi new_remainder=$ if [ "$new_remainder" = "$remainder" ] then echo "No more titles" exit fi remainder=$new_remainder done 

remainder=$это форма раскрытия параметров, которая удаляет соответствующий шаблон префикса. Здесь он устанавливает remainderдля

  • Первый заголовок в строке ( исключая вступительный <title>),
  • отставая </title>, и
  • все остальные строки после этого (включая все последующие заголовки).

Если "$WP055" = "$remainder", это означает, что оболочка не найдена <title>в строке.

this_title=$Аналогично устанавливается this_title, что $remainderдо, но не включая первый </title>.

if [[ something1 == something2 ]]с двойными скобками ( [[ … ]]) и двойным знаком равенства ( ==) соответствует шаблону. Все остальное - повторение.

Это может вести себя странно при неправильном вводе; т.е. текст, где <title>и </title>не встречаются в чередующихся парах.