Интересно общее правило использовать регулярное выражение в выражении if в ударе?
Вот пример
$ gg=svm-grid-ch
$ if [[ $gg == *grid* ]] ; then echo $gg; fi
svm-grid-ch
$ if [[ $gg == ^....grid* ]] ; then echo $gg; fi
$ if [[ $gg == ....grid* ]] ; then echo $gg; fi
$ if [[ $gg == s...grid* ]] ; then echo $gg; fi
$
Почему последние три сбоя, которые будут соответствовать?
Надежда Вы могли дать как можно больше общих правил, не только для этого примера.
При использовании шаблона глобуса вопросительный знак представляет один символ, а звездочка представляет собой последовательность из нуля или более символов:
if [[ $gg == ????grid* ]] ; then echo $gg; fi
При использовании обычного В выражении точка представляет один символ, а звездочка представляет ноль или более предшествующих символов. Таким образом, «. *
» представляет ноль или более любого символа, « a *
» представляет ноль или более «a», « [0-9] *
"представляет ноль или более цифр. Еще один полезный (среди многих) знак плюс, который представляет один или несколько предшествующих символов. Таким образом, « [a-z] +
» представляет один или несколько букв нижнего регистра (в локали C и некоторых других).
if [[ $gg =~ ^....grid.*$ ]] ; then echo $gg; fi
Используйте = ~
для проверки регулярных выражений Учебное пособие по регулярным выражениям Содержание
@OP,
Используется ли glob pettern не только для имен файлов?
Нет, шаблон «glob» используется не только для имен файлов. вы также можете использовать его для сравнения строк. В ваших примерах вы можете использовать case / esac для поиска шаблонов строк.
gg=svm-grid-ch
# looking for the word "grid" in the string $gg
case "$gg" in
*grid* ) echo "found";;
esac
# [[ $gg =~ ^....grid* ]]
case "$gg" in ????grid*) echo "found";; esac
# [[ $gg =~ s...grid* ]]
case "$gg" in s???grid*) echo "found";; esac
В bash, когда использовать шаблон глобуса, а когда использовать регулярное выражение? Спасибо!
Регулярные выражения более универсальны и «удобны», чем «глобальные шаблоны», однако, если вы не выполняете сложные задачи, которые «глобальное / расширенное глобальное выражение» не может обеспечить легко, тогда нет необходимости использовать регулярное выражение.
Регулярные выражения не поддерживаются для версии bash <3.2 (как упоминал Деннис), но вы все равно можете использовать расширенную глобализацию (установив extglob
). для расширенных глобусов см. здесь и несколько простых примеров здесь .
Обновление для OP: Пример поиска файлов, которые начинаются с 2 символов (точки «.» Означает 1 символ), за которыми следует «g» с использованием регулярного выражения
, например, output
$ shopt -s dotglob
$ ls -1 *
abg
degree
..g
$ for file in *; do [[ $file =~ "..g" ]] && echo $file ; done
abg
degree
..g
В приведенном выше примере файлы совпадают, потому что их имена содержат 2 символа, за которыми следует буква «g». (т.е. .. g
).
Эквивалент подстановки будет примерно таким: (см. ссылку , чтобы узнать значение ?
и *
)
$ for file in ??g*; do echo $file; done
abg
degree
..g
Добавление этого решения с помощью встроенных grep
и базовых sh
для тех, кто заинтересован в более переносимом решении (независимо от версия bash
; также работает со старым простым sh
, на платформах, отличных от Linux и т. Д.)
# GLOB matching
gg=svm-grid-ch
case "$gg" in
*grid*) echo $gg ;;
esac
# REGEXP
if echo "$gg" | grep '^....grid*' >/dev/null ; then echo $gg ; fi
if echo "$gg" | grep '....grid*' >/dev/null ; then echo $gg ; fi
if echo "$gg" | grep 's...grid*' >/dev/null ; then echo $gg ; fi
# Extended REGEXP
if echo "$gg" | egrep '(^....grid*|....grid*|s...grid*)' >/dev/null ; then
echo $gg
fi
Некоторые версии grep
также поддерживают -q
(тихий) вариант в качестве альтернативы перенаправлению на / dev / null
, но перенаправление снова является наиболее переносимым.