Zastanawiam się, jaka jest ogólna zasada używania wyrażenia regularnego w klauzuli if w bash?
Oto przykład
$ 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
$
Dlaczego ostatnie trzy nie pasują?
Mam nadzieję, że możesz podać jak najwięcej ogólnych zasad, nie tylko na potrzeby tego przykładu.
Posługiwać się
=~
aby zapoznać się z wyrażeniami regularnymi, sprawdź Spis treści samouczka dotyczącego wyrażeń regularnych
źródło
if [[ $gg =~ ^....grid.* ]]
źródło
Dodanie tego rozwiązania z
grep
podstawowymish
wbudowanymi wersjami dla osób zainteresowanych bardziej przenośnym rozwiązaniem (niezależnie odbash
wersji; działa również ze zwykłym starymsh
, na platformach innych niż Linux itp.)# 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
Niektóre
grep
inkarnacje obsługują również-q
opcję (cichą) jako alternatywę dla przekierowania do/dev/null
, ale przekierowanie jest ponownie najbardziej przenośne.źródło
grep -q
zamiastgrep >/dev/null
.@OP,
Nie, wzorzec „glob” jest używany nie tylko w nazwach plików. używasz go również do porównywania łańcuchów. W swoich przykładach możesz użyć przypadku / esac, aby wyszukać wzorce łańcuchów.
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
Regex są bardziej wszechstronne i „wygodne” niż „wzorce globalne”, jednak jeśli nie wykonujesz złożonych zadań, których „globalizacja / rozszerzone globowanie” nie może łatwo zapewnić, nie ma potrzeby używania wyrażenia regularnego. Regex nie jest obsługiwany w wersji bash <3.2 (jak wspomniał Dennis), ale nadal możesz używać rozszerzonego globowania (poprzez ustawienie
extglob
). rozszerzony globbing, zobacz tutaj i kilka prostych przykładów tutaj .Aktualizacja dla OP: przykład wyszukiwania plików, które zaczynają się od 2 znaków (kropki „.” Oznaczają 1 znak), po których następuje „g” przy użyciu wyrażenia regularnego
np. wyjście
$ shopt -s dotglob $ ls -1 * abg degree ..g $ for file in *; do [[ $file =~ "..g" ]] && echo $file ; done abg degree ..g
W powyższym przypadku pliki są dopasowywane, ponieważ ich nazwy zawierają 2 znaki, po których następuje „g”. (tj
..g
.).Odpowiednik z globbingiem będzie wyglądał mniej więcej tak: (spójrz na odniesienie dla znaczenia
?
i*
)$ for file in ??g*; do echo $file; done abg degree ..g
źródło
ls ..g
nie działa. Mówisz powłoce, aby szukała pliku o nazwie..g
. Co do poznawania składni regex, można spróbowaćperldoc perlretut
,perldoc perlrequick
albo zrobićinfo sed
z linii poleceń.