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

1

В скрипте 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 по тихоокеанскому времени, когда текущее уведомление о ветре будет отменено.)

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

Ответы:

0

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

WP055="$(wget -qO - http://alerts.weather.gov/cap/wwaatmget.php?x=CAZ055&y=1)"
remainder=${WP055#*<title>}
if [ "$WP055" = "$remainder" ]
then
        echo "No title found"
        exit
fi
while true
do
        this_title=${remainder%%</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=${remainder#*<title>}
        if [ "$new_remainder" = "$remainder" ]
        then
                echo "No more titles"
                exit
        fi
        remainder=$new_remainder
done

remainder=${WP055#*<title>}это форма раскрытия параметров, которая удаляет соответствующий шаблон префикса. Здесь он устанавливает remainderдля

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

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

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

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

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

G-Man
источник