используйте регулярное выражение в if-condition в bash



интересно, общее правило для использования регулярного выражения в предложении if в bash?



вот пример



$ 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
$


почему последние три не совпадает?



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

663   5  

5 ответов:

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

if [[ $gg == ????grid* ]] ; then echo $gg; fi

при использовании регулярного выражения точка представляет один символ, а звездочка-ноль или более предыдущего символа. Так что".*" означает ноль или более любых символов "a* " представляет ноль или более "a","[0-9]*" означает ноль или более цифр. Еще один полезный (среди многих) является плюсом знак, который представляет один или несколько из предыдущих символов. Так что"[a-z]+ " представляет один или несколько строчных Альфа-символов (в локале C - и некоторых других).

if [[ $gg =~ ^....grid.*$ ]] ; then echo $gg; fi

использовать =~

для проверки регулярных выражений регулярные выражения учебник Оглавление

if [[ $gg =~ ^....grid.* ]]

добавление этого решения с grep и basic sh builtins для тех, кто заинтересован в более портативном решении (независимо от 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, но перенаправление снова является самым портативным.

@OP,

Is glob pettern not only used for file names?

нет, шаблон "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

In bash, when to use glob pattern and when to use regular expression? Thanks!

регулярные выражения более универсальны и" удобны", чем" шаблоны глобуса", однако, если вы не выполняете сложные задачи, которые" глобирование/расширенное глобирование " не может обеспечить легко, тогда нет необходимости использовать регулярное выражение. Регулярные выражения не поддерживаются по версии Баш extglob). для расширенного имени, см. здесь и несколько простых примеров здесь.

обновление для OP: пример поиска файлов, которые начинаются с 2 символов (точки "."означает 1 символ), за которым следует "g", используя регулярное выражение

например, выход

$ shopt -s dotglob
$ ls -1 *
abg
degree
..g

$ for file in *; do [[ $file =~ "..g" ]] && echo $file ; done
abg
degree
..g

в приведенном выше, файлы сопоставляются, потому что их имена содержат 2 символа, за которыми следуют "г." (то есть ..g).

эквивалент с глоббинг будет что-то вроде этого: (посмотри ссылка смысла ? и *)

$ for file in ??g*; do echo $file; done
abg
degree
..g

Comments

    Ничего не найдено.