본문 바로가기
IT일반/Linux

Command Line - 정규 표현식

by 버섯도리 2022. 6. 1.

<grep 옵션>

옵션 설명
-i 대소문자 무시. --ignore-case로도 지정할 수 있다.
-v 반전 매치. 이 옵션은 grep이 일치하지 않는 모든 행을 출력하도록 한다. --invert-match로도 지정할 수 있다.
-c 일치한 행(-v 옵션을 사용하면 일치하지 않는 행) 자체가 아닌 행의 수를 출력한다. --count로도 지정할 수 있다.
-l 일치한 행 자체가 아닌 이를 포함한 각각의 파일 이름을 출력한다. --files-with-matches로도 지정할 수 있다.
-L -l 옵션과 유사하지만 일치하는 행이 없는 파일의 이름만을 출력한다. --files-without-matches로도 지정할 수 있다.
-n 일치하는 행 앞에 파일의 행 번호를 붙인다. --line-number로도 지정할 수 있다.
-h 복수 파일 검색에서 파일명의 출력을 숨긴다. --no-filename으로도 지정할 수 있다.

 

[cmd_test@btjeon-naver ~]$ ls /bin > dirlist-bin.txt
[cmd_test@btjeon-naver ~]$ ls /usr/bin > dirlist-usr-bin.txt
[cmd_test@btjeon-naver ~]$ ls /sbin > dirlist-sbin.txt
[cmd_test@btjeon-naver ~]$ ls /usr/sbin > dirlist-usr-sbin.txt
[cmd_test@btjeon-naver ~]$ ls dirlist*.txt
dirlist-bin.txt  dirlist-sbin.txt  dirlist-usr-bin.txt  dirlist-usr-sbin.txt
[cmd_test@btjeon-naver ~]$ 
[cmd_test@btjeon-naver ~]$ grep bzip dirlist*.txt
dirlist-bin.txt:bzip2
dirlist-bin.txt:bzip2recover
dirlist-usr-bin.txt:bzip2
dirlist-usr-bin.txt:bzip2recover
[cmd_test@btjeon-naver ~]$ grep -l bzip dirlist*.txt
dirlist-bin.txt
dirlist-usr-bin.txt
[cmd_test@btjeon-naver ~]$ grep -L bzip dirlist*.txt
dirlist-sbin.txt
dirlist-usr-sbin.txt

grep 명령어로 bzip 문자열을 가진 모든 파일 목록을 검색해서 파일명:문자 포맷으로 출력한다.

파일 목록에만 관심이 있다면 -l, 일치하지 않는 파일들만 보고 싶다면 -L 옵션으로 확인할 수 있다.

 

[cmd_test@btjeon-naver ~]$ grep -h '.zip' dirlist*.txt
bunzip2
bzip2
bzip2recover
funzip
gpg-zip
gunzip
gzip
unzip
unzipsfx
bunzip2
bzip2
bzip2recover
funzip
gpg-zip
gunzip
gzip
unzip
unzipsfx

zip 문자를 포함하는 모든 행을 출력한다.

(.zip 정규표현식의 도트(.) 문자로 인해 최소 네 문자의 일치가 필요하여 zip이라는 문자는 출력되지 않는다.)

 

[cmd_test@btjeon-naver ~]$ grep -h '^zip' dirlist*.txt
zip
zipcloak
zipgrep
zipinfo
zipnote
zipsplit
zip
zipcloak
zipgrep
zipinfo
zipnote
zipsplit

캐럿(^) 문자는 행의 시작에서 해당 정규 표현식이 발견되는 경우에만 출력한다.

 

[cmd_test@btjeon-naver ~]$ grep -h 'zip$' dirlist*.txt
funzip
gpg-zip
gunzip
gzip
unzip
zip
funzip
gpg-zip
gunzip
gzip
unzip
zip

달러($) 문자는 행의 끝에서 해당 정규 표현식이 발견되는 경우에만 출력한다.

 

[cmd_test@btjeon-naver ~]$ grep -i '^..j.r$' /usr/share/dict/words
Bajer
Bojer
Gujar
Kajar
Major
major

세번째 글자는 j, 마지막 글자는 r인 단어를 찾고 싶을 때

 

[cmd_test@btjeon-naver ~]$ grep -h '[bg]zip' dirlist*.txt
bzip2
bzip2recover
gzip
bzip2
bzip2recover
gzip

bzip 또는 gzip 문자열을 포함한 모든 행을 출력한다.

 

[cmd_test@btjeon-naver ~]$ grep -h '[^bg]zip' dirlist*.txt
bunzip2
funzip
gpg-zip
gunzip
unzip
unzipsfx
bunzip2
funzip
gpg-zip
gunzip
unzip
unzipsfx

괄호 표현식 내의 캐럿(^)은 부정을 나타내며, 위의 경우에는 zip 문자열 앞에 b나 g를 제외한 문자를 가진 행만 출력한다.

(캐럿 문자는 괄호 표현식의 첫번째 문자인 경우에만 부정을 나타낸다.)

 

[cmd_test@btjeon-naver ~]$ grep -h '^[A-Z]' dirlist*.txt
Mail
NetworkManager
Mail
NetworkManager

대문자로 시작하는 이름을 가진 모든 행을 출력한다.

 

<POSIX 문자 클래스>

문자 클래스 설명
[:alnum:] ASCII 알파벳과 숫자; [A-Za-z0-9]와 동일
[:word:] [:alnum:]과 동일. 밑줄(_) 문자 추가됨
[:alpha:] ASCII 알파벳; [A-Za-z]와 동일
[:blank:] 스페이스와 탭 문자
[:cntrl:] ASCII 제어코드; ASCII 문자 0부터 31과 127번
[:digit:] 숫자 0부터 9
[:graph:] 출력 가능한 그래픽 문자; ASCII 문자 33부터 126까지
[:lower:] 소문자
[:punct:] ASCII 구두점 기호; [-!"#$%&'()*+,./:;<=>?@[\\\]_`{\}~]와 동일
[:print:] 출력 가능 문자; [:graph:]에 스페이스 문자 추가
[:space:] 공백 문자, ASCII의 스페이스, 탭, 캐리지 리턴, 개행, 수직 탭, 폼 피드를 포함; [ \t\r\n\v\f]와 동일
[:upper:] 대문자
[:xdigit:] 16진수를 표현하는 ASCII 문자; [0-9A-Fa-f]와 동일

 

[cmd_test@btjeon-naver ~]$ ls /usr/sbin/[[:upper:]]*
/usr/sbin/NetworkManager

대문자로 시작하는 이름을 가진 파일을 출력한다.

 

[cmd_test@btjeon-naver ~]$ echo "AAA" | grep -E 'AAA|BBB'
AAA

-E 옵션을 사용하면 확장 정규 표현식(ERE)를 사용할 수 있다. 위와 같은 경우는 AAA나 BBB 문자열 중에서 일치하는 것을 찾으라는 뜻이다.

 

[cmd_test@btjeon-naver ~]$ grep -Eh '^(bz|gz|zip)' dirlist*.txt
bzcat
bzcmp
bzdiff
bzgrep
bzip2
...
gzexe
gzip
zip
zipcloak
zipgrep
zipinfo
zipnote
zipsplit
...

이 표현식은 bz, gz 또는 zip으로 시작하는 파일을 찾아줄 것이다.

 

[cmd_test@btjeon-naver ~]$ echo "(555) 123-4567" | grep -E '^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$'
(555) 123-4567
[cmd_test@btjeon-naver ~]$ echo "555 123-4567" | grep -E '^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$'
555 123-4567
[cmd_test@btjeon-naver ~]$ echo "AAA 123-4567" | grep -E '^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$'

? - 항목이 없거나 한 번만 나타나는 경우 - 전화번호의 유효성 검사 예

 

[cmd_test@btjeon-naver ~]$ echo "This works." | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.'
This works.
[cmd_test@btjeon-naver ~]$ echo "This Works." | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.'
This Works.
[cmd_test@btjeon-naver ~]$ echo "This does not" | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.'

* - 항목이 없거나 여러 번 나타나는 경우 - 한 문자열이 대문자로 시작하고 여러 대소문자와 공백을 포함하고 있으며 마지막은 마침표로 끝나는 문장을 검사

 

[cmd_test@btjeon-naver ~]$ echo "This that" | grep -E '^([[:alpha:]]+ ?)+$'
This that
[cmd_test@btjeon-naver ~]$ echo "a b c" | grep -E '^([[:alpha:]]+ ?)+$'
a b c
[cmd_test@btjeon-naver ~]$ echo "a b 9" | grep -E '^([[:alpha:]]+ ?)+$'
[cmd_test@btjeon-naver ~]$ echo "abc  d" | grep -E '^([[:alpha:]]+ ?)+$'

+ - 항목이 한 번 이상 나타나는 경우 - 단일 스페이스로 구분된 하나 이상의 알파벳으로 구성된 그룹을 찾기 예

 

[cmd_test@btjeon-naver ~]$ echo "(555) 123-4567" | grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$'
(555) 123-4567
[cmd_test@btjeon-naver ~]$ echo "555 123-4567" | grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$'
555 123-4567
[cmd_test@btjeon-naver ~]$ echo "5555 123-4567" | grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$'

{} - 항목이 지정된 횟수만큼 나타나는 경우 - 전화번호의 유효성 검사 예 더 간단하게

 

<일치 횟수 지정>

명시자 의미
{n} 정확히 n번만 일치하는 선행 요소 검색
{n,m} n번 이상, m번 미만으로 일치하는 선행 요소 검색
{n,} n번 이상으로 일치하는 선행 요소 검색
{,m} m번 미만으로 일치하는 선행 요소 검색

 

[cmd_test@btjeon-naver ~]$ for i in {1..10}; do echo "(${RANDOM:0:3}) ${RANDOM:0:3}-${RANDOM:0:4}" >> phonelist.txt; done
[cmd_test@btjeon-naver ~]$ cat phonelist.txt 
(142) 369-1512
(302) 163-335
(424) 230-2990
(300) 107-7548
(300) 159-2344
(284) 106-2874
(203) 192-2298
(170) 185-1743
(236) 108-2170
(217) 877-2388
[cmd_test@btjeon-naver ~]$ grep -Ev '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$' phonelist.txt 
(302) 163-335

유효하지 않은 전화번호 찾는 예 (-v 옵션)

 

[cmd_test@btjeon-naver ~]$ find . -regex '.*[^-_./0-9a-zA-Z].*'
./two words.txt

find 명령어의 정규 표현식으로 숨겨진 공백 문자나 잠재적으로 문제가 되는 다른 문자가 포함된 경로명 찾기 예

([-_./0-9a-zA-Z] 집합에 포함되지 않는 경로명을 찾음. 부정 괄호식 사용(^))

(.*을 표현식 끝에 모두 사용하여 해당 문자가 존재하지 않거나 한 번 이상 존재하는 개체를 찾도록 하였다.)

 

[cmd_test@btjeon-naver ~]$ locate --regex 'bin/(bz|gz|zip)'
/usr/bin/bzcat
/usr/bin/bzcmp
/usr/bin/bzdiff
/usr/bin/bzgrep
/usr/bin/bzip2
/usr/bin/bzip2recover
/usr/bin/bzless
/usr/bin/bzmore
/usr/bin/gzexe
/usr/bin/gzip
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit

locate 명령어의 정규 표현식으로 경로명 검색

 

[cmd_test@btjeon-naver ~]$ less phonelist.txt
----------------------------------------------------------------------
(142) 369-1512
(302) 163-335
(424) 230-2990
(300) 107-7548
(300) 159-2344
(284) 106-2874
(203) 192-2298
(170) 185-1743
(236) 108-2170
(217) 877-2388
/^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$
----------------------------------------------------------------------

less 명령어로 유효하지 않은 전화번호 찾기 예 (/ 키를 입력하고 정규 표현식을 입력)

 

[cmd_test@btjeon-naver ~]$ vi phonelist.txt
----------------------------------------------------------------------
(142) 369-1512
(302) 163-335
(424) 230-2990
(300) 107-7548
(300) 159-2344
(284) 106-2874
(203) 192-2298
(170) 185-1743
(236) 108-2170
(217) 877-2388
/([0-9]\{3\}) [0-9]\{3\}-[0-9]\{4\}
----------------------------------------------------------------------

vi 편집기에서 유효한 전화번호 찾기 예 (/ 키를 입력하고 정규 표현식을 입력, (와 } 기호 표현이 less와 다름.)

(vi는 기본 정규 표현식을 사용해서 {와 같은 메타문자로 여겨지는 문자들을 리터럴 문자로 받아들인다. 백슬래시(\)를 추가하면 메타문자로 인식한다.)

 

[cmd_test@btjeon-naver ~]$ cd /usr/share/man/man1
[cmd_test@btjeon-naver man1]$ zgrep -El 'regex|regular expression' *.gz
...
xzegrep.1.gz
xzfgrep.1.gz
xzgrep.1.gz
zgrep.1.gz
zip.1.gz
zmore.1.gz

zgrep 명령어는 압축 파일을 읽어서 검사할 수 있다.

 

 

 

 

 

 

 

출처 : 리눅스 커맨드라인 완벽 입문서

 

'IT일반 > Linux' 카테고리의 다른 글

Command Line - 출력 포맷 지정  (0) 2022.06.02
Command Line - 텍스트 편집  (0) 2022.06.01
Command Line - 파일 보관 및 백업  (0) 2022.05.31
Command Line - 파일 검색  (0) 2022.05.28
Command Line - 네트워킹  (0) 2022.05.28