Pattern Matching

Regular expression 이 [[ ]] 표현식에 한에서 제한적으로 사용할 수 있다면 glob 문자 ( *, ?, [ ] ) 를 이용하는 패턴 매칭은 쉘 스크립트 전반에서 사용할 수 있습니다.

  • filename matching ( globbing )
  • case 문 에서
  • 매개변수 확장에서 ( substring removal, search and replace )
  • [[ ]] 표현식 에서

Glob 문자의 의미

문자 의미
* empty 를 포함해 모든 문자와 매치됩니다.
? 임의의 문자 하나와 매치됩니다.
[ . . . ] bracket 표현식 내의 하나의 문자와 매치됩니다.

Bracket 표현식

표현식 의미
[XYZ] X or Y or Z 문자에 대해 매치됩니다.
[X-Z] 위 표현식을 - 문자를 이용해 range 로 나타낼수 있습니다.
[[:class:]] POSIX character class 와 매치됩니다.
[^ . . . ]
[! . . . ]
^ , ! 문자는 NOT 을 의미합니다.
가령 [^XYZ] 이라면 XYZ 이외의 문자와 매치됩니다.

- 를 일반 문자로 사용할 때는 두 문자 사이에 위치하지 않게 마지막이나 처음에 위치시키면 됩니다.
], [ 문자는 처음에 위치시키면 됩니다.

Character Classes

문자들을 비슷한 의미를 가진 그룹으로 나누어놓은 것이 character classes 입니다. [[:alnum:]] 의미는 [ ] bracket 표현식 내에서 [:alnum:] 이라는 클래스가 사용되어 결과적으로 [A-Za-z0-9] 의미를 가지게 됩니다. 따라서 [[:upper:][:digit:]] 의 의미는 [A-Z0-9] 와 같게 됩니다.

Class Represented Description
[[:alnum:]] [A-Za-z0-9] Alphanumeric characters
[[:alpha:]] [A-Za-z] Alphabetic characters
[[:lower:]] [a-z] Lower-case alphabetic characters
[[:upper:]] [A-Z] Upper-case alphabetic characters
[[:digit:]] [0-9] Numeric characters
[[:xdigit:]] [0-9a-fA-F] Hexadecimal digit characters
[[:space:]] [ \t\n\v\f\r] All whitespace chars (form feed \x0c)
[[:blank:]] [ \t] Space, tab only
[[:punct:]] [!@#$%^&*(){}[]...] 키보드에 있는 숫자, 대,소문자 빼고 모든 문자
[[:graph:]] [!-~] Printable and visible characters
(ASCII 테이블에서 ! 부터 ~ 까지)
[[:print:]] [ -~] Printable (non-Control) characters
(ASCII 테이블에서 space 부터 ~ 까지)
[[:cntrl:]] [\x00-\x19\x7F] Control characters

[[:graph:]][[:print:]] 는 space 를 포함하고 안 하고 차이

사용예 )

$ ls
address.class  address.java  read.c  read.h  write.c  write.h

$ ls *.[ch]
read.c  read.h  write.c  write.h
.............................................................

$ AA="inventory.tar.gz"

$ [[ $AA = *.tar.gz ]]; echo $?
0
$ [[ $AA = inventory.tar.?? ]]; echo $?
0

# 패턴에 공백을 사용하려면 escape 합니다.
$ AA='hello dog cat world'

$ [[ $AA = *dog\ cat* ]]; echo $?
0

Extended Pattern

이것은 bash 에서만 제공되는 기능으로 shopt -s extglob 옵션을 설정하면 다음과 같은 확장 패턴을 사용할 수 있습니다. | 문자를 구분자로 하여 여러 개의 패턴을 사용할 수 있습니다.

표현식 의미
?(<PATTERN-LIST>) 주어진 패턴이 zero or one 발생하면 매치됩니다.
*(<PATTERN-LIST>) 주어진 패턴이 zero or more 발생하면 매치됩니다.
+(<PATTERN-LIST>) 주어진 패턴이 one or more 발생하면 매치됩니다.
@(<PATTERN-LIST>) 주어진 패턴이 one 발생하면 매치됩니다.
!(<PATTERN-LIST>) ! 문자는 Not 의 의미로 주어진 패턴과 맞지 안으면 매치됩니다.

사용예 )

# *.jpg 파일을 제외하고 전부
$ ls !(*.jpg)

# *.jpg , *.gif , *.png 파일을 제외하고 전부 
$ ls !(*.jpg|*.gif|*.png)

# AA 변수값의 leading space 와 trailing space 를 제거
$ AA=${AA##+([[:blank:]])}; AA=${AA%%+([[:blank:]])}

---------------------------------------------------

$ AA=apple

$ [[ $AA = @(ba*(na)|a+(p)le) ]]; echo $?
0

$ AA=banana

$ [[ $AA = @(ba*(na)|a+(p)le) ]]; echo $?
0

$ AA=applebanana

$ [[ $AA = @(ba*(na)|a+(p)le) ]]; echo $?
1

$ [[ $AA = +(ba*(na)|a+(p)le) ]]; echo $?
0