Подтвердить что ты не робот

Оболочка script. как извлечь строку, используя регулярные выражения

Я новичок в сценариях оболочки. Я хочу отправить запрос http с помощью curl, а затем извлечь некоторую строку, используя регулярные выражения. Например, как я могу извлечь доменное имя из ответа HTTP? (Пример только для учебных целей)

#!/bin/bash
name=$(curl google.com | grep "www\..*com")
echo "domain name is"
echo $name
4b9b3361

Ответ 1

Использование bash регулярных выражений:

re="http://([^/]+)/"
if [[ $name =~ $re ]]; then echo ${BASH_REMATCH[1]}; fi

Изменить - ОП запросил объяснение синтаксиса. Синтаксис регулярных выражений - это большая тема, которую я не могу полностью объяснить здесь, но я попытаюсь объяснить достаточно, чтобы понять этот пример.

re="http://([^/]+)/"

Это регулярное выражение, хранящееся в переменной bash, re - то есть, что вы хотите, чтобы ваша строка ввода соответствовала, и, надеюсь, извлечение подстроки. Разрушение:

  • http:// - это просто строка - входная строка должна содержать эту подстроку для регулярного выражения, соответствующего
  • [] Обычно используются квадратные скобки, которые "соответствуют любому символу в скобках". Таким образом, c[ao]t будет соответствовать как "cat", так и "cot". Символ ^ в пределах [] изменяет это так, чтобы сказать: "соответствовать любому символу, кроме тех, что заключены в квадратные скобки. Поэтому в этом случае [^/] будет соответствовать любому символу, кроме" /".
  • Выражение квадратной скобки будет соответствовать только одному символу. Добавление + в конец этого слова "соответствует 1 или более из предыдущего подвыражения". Таким образом, [^/]+ соответствует 1 или более из набора всех символов, исключая "/" .
  • Ввод () круглых скобок вокруг подвыражения говорит о том, что вы хотите сохранить все, что соответствовало этому подвыражению для последующей обработки. Если используемый вами язык поддерживает это, он предоставит некоторый механизм для извлечения этих подматричек. Для bash это массив BASH_REMATCH.
  • Наконец, мы выполняем точное совпадение на "/" , чтобы убедиться, что мы полностью сопоставим с полным доменным именем и следующим "/"

Далее, мы должны проверить входную строку на регулярное выражение, чтобы увидеть, совпадает ли оно. Мы можем использовать условие bash для этого:

if [[ $name =~ $re ]]; then
    echo ${BASH_REMATCH[1]}
fi

В bash [[ ]] укажите расширенный условный тест и может содержать оператор регулярного выражения =~ bash. В этом случае мы проверяем, соответствует ли входная строка $name регулярному выражению $re. Если он соответствует, то из-за построения регулярного выражения мы гарантируем, что у нас будет подделка (из круглых скобок ()), и мы можем получить к ней доступ с помощью массива BASH_REMATCH:

  • Элемент 0 этого массива ${BASH_REMATCH[0]} будет всей строкой, согласованной с регулярным выражением, т.е. " http://www.google.com/".
  • Последующими элементами этого массива будут последующие результаты подматричек. Обратите внимание, что вы можете иметь несколько подгрузок () в пределах регулярного выражения - элементы BASH_REMATCH будут соответствовать им в порядке. Поэтому в этом случае ${BASH_REMATCH[1]} будет содержать "www.google.com", который, я думаю, является нужной строкой.

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

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


Обратите внимание, что вместо того, чтобы устанавливать переменную $re в отдельной строке и ссылаясь на эту переменную в условии, вы можете поместить регулярное выражение непосредственно в условие. Однако в bash 3.2 правила были изменены в отношении того, нужны ли кавычки вокруг таких литералов регулярных выражений или нет. Помещение регулярного выражения в отдельную переменную является простым способом вокруг этого, так что условие работает как ожидалось во всех версиях bash, которые поддерживают оператор соответствия =~.

Ответ 2

Один из способов: sed. Например:

echo $name | sed -e 's?http://www\.??'

Обычно регулярные выражения sed ограничиваются символом `/', но вы можете использовать'? ' так как вы ищете '/'. Вот еще трюк bash. Ответ @DigitalTrauma напомнил мне, что я должен это предложить. Это похоже:

echo ${name#http://www.}

(DigitalTrauma также получает кредит за то, что напомнил мне, что нужно обрабатывать "http://".)