And Brain said,
정규표현식(Regular Expression), 데이터를 걸러내는 디지털 어망 본문
정규표현식?
로그 분석, 데이터 필터링, 크롤링, 보안, 데이터 정제 등 다양한 분야에서 사용되는 정규표현식(Regular Expression, regex, regexp)에 대해서 한 번 쯤은 들어보셨을 것입니다.
이 정규식은 잘만 사용하신다면 여러분들에게 문자열에서 특정 패턴을 찾아내거나 변환해주는 강력한 어망이 되어줄 것입니다.
여기서는 기본적으로 리눅스에서 정규식을 사용하는 예제들로 알아볼 것입니다.
먼저, 리눅스에서 자주 쓰는 정규표현식(Regex) 패턴들을 정리해보자면 아래와 같습니다.
. | 임의의 한 문자(줄바꿈 제외) | h.t → hat, hit, hot |
^ | 문자열의 시작 | ^ERROR → "ERROR 123" 매칭 |
$ | 문자열의 끝 | fail$ → "test fail" 매칭 |
* | 0개 이상 반복 | ab*c → ac, abc, abbc |
+ | 1개 이상 반복 | ab+c → abc, abbc (X: ac) |
? | 0개 또는 1개 | colou?r → color, colour |
{n,m} | n~m번 반복 | a{2,4} → aa, aaa, aaaa |
[abc] | a, b, c 중 하나 | gr[ae]y → gray, grey |
[^abc] | a, b, c 제외한 문자 | [^0-9] → 숫자가 아닌 문자 |
\d | 숫자 ([0-9]와 동일) | \d{3} → "123", "456" |
\w | 단어 문자 ([a-zA-Z0-9_]) | \w+ → "hello", "test_123" |
\s | 공백 문자 (스페이스, 탭 등) | \s+ → " " (공백 여러 개) |
() | 그룹화 | (ab)+ → "ab", "abab" |
| | 연산자 | OR (또는) |
이제 위 정규표현식을 리눅스 명령어들과 함께 실전 예제로 살펴봅시다.
보통 리눅스에서 정규표현식을 활용하여 자주 사용되는 명령어는 아래와 같습니다.
grep | 특정 패턴을 포함한 행을 출력 |
egrep | grep -E와 동일 (확장 정규표현식 지원) |
sed | 문자열 치환 및 텍스트 변환 |
awk | 필드 기반 텍스트 처리 |
find | 파일 검색 |
perl | 강력한 정규표현식 지원 |
grep에 대해 더 궁금하시다면 아래 링크를 참고해주세요,
https://theworldaswillandidea.tistory.com/entry/grep
grep, linux command 옵션 총정리
제가 쓰려고 정리해놓은거라 설명이 부족한 점 양해바랍니다. 1. 기본 사용법 grep [옵션] "검색할_패턴" 파일명grep "error" log.txt 👉 log.txt에서 "error"라는 단어가 포함된 줄을 출력 2. grep의 모든
theworldaswillandidea.tistory.com
그러면, 이 각각의 명령어들을 통해 정규표현식을 직접 활용해보는 시간을 가져봅시다.
grep을 활용한 정규표현식 필터링
1. 특정 단어가 포함된 로그 검색
grep "error" /var/log/syslog
"error"라는 단어가 포함된 모든 로그를 찾습니다.
grep은 기본적으로 부분 매칭을 수행하므로 "error123", "my_error" 등도 검색되며, 대소문자를 구분하므로 "ERROR"는 찾지 않습니다.
* 대소문자를 무시하려면 -i 옵션을 사용하시면 됩니다.
grep -i "error" /var/log/syslog
2. 특정 IP 주소 패턴 찾기
grep -E "192\.168\.[0-9]{1,3}\.[0-9]{1,3}" access.log
192.168.*.* 형태의 IP 주소를 찾습니다.
\. → .은 정규표현식에서 **"임의의 한 문자"**를 의미하므로, 진짜 점(.)을 찾으려면 \.로 이스케이프를 해야 합니다.
[0-9]{1,3} → 1~3자리 숫자 (ex: 192, 8, 168)
-E 옵션을 사용하면 확장 정규표현식을 적용할 수 있습니다.
3. 특정 시간대 로그 찾기
grep -E "^2024-02-04 1[3-5]:" /var/log/syslog
"2024-02-04 13:xx" ~ "2024-02-04 15:xx" 시간대 로그만 검색합니다.
^2024-02-04 → "2024-02-04"로 시작하는 행
1[3-5]: → "13:", "14:", "15:" 패턴을 찾습니다.
4. 특정 포트를 사용하는 로그 필터링 (SSH 22번 포트)
grep -E "192\.168\.1\.[0-9]+:22" /var/log/auth.log
192.168.1.*:22 형태로 접속한 로그만 찾습니다.
[0-9]+ → 1개 이상의 숫자 (즉, IP의 마지막 자리)
5. 여러 개의 특정 문자열 검색 (ERROR, WARN, CRITICAL)
grep -E "ERROR|WARN|CRITICAL" /var/log/syslog
"ERROR", "WARN", "CRITICAL" 중 하나라도 포함된 행을 출력합니다.
| → OR 연산자
-E를 붙여야 확장 정규표현식(egrep과 동일)으로 인식됩니다.
egrep을 활용한 정규표현식 필터링
1. 특정 날짜 로그 필터링
egrep "^(2024-02-0[1-5])" /var/log/syslog
"2024-02-01"부터 "2024-02-05"까지의 로그를 출력합니다.
^ → 행의 시작
2. 이메일 주소만 추출
egrep -o "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" emails.txt
[a-zA-Z0-9._%+-]+ → 이메일 사용자명
@ → 고정 문자
[a-zA-Z0-9.-]+ → 도메인명
\.[a-zA-Z]{2,} → .com, .net 같은 도메인 확장자
3. URL 찾기
egrep -o "https?://[a-zA-Z0-9./?=_-]+" web_data.txt
https?:// → http:// 또는 https://
[a-zA-Z0-9./?=_-]+ → URL에서 사용될 수 있는 문자들
4. 로그에서 특정 상태 코드 찾기 (200, 404, 500)
egrep "(200|404|500) .* /index.html" access.log
200, 404, 500 중 하나
.* → 임의의 문자 여러 개
/index.html이 포함된 로그
5. 숫자로만 이루어진 행 찾기
egrep "^[0-9]+$" data.txt
^[0-9]+$ → 숫자로만 이루어진 행
sed를 활용한 정규표현식 필터링
1. 특정 단어 치환
sed 's/error/failure/g' log.txt
s/error/failure/g → "error"를 "failure"로 변경
s/old/new/ → old를 new로 치환하는 패턴
g 플래그를 추가하면 한 줄에서 "error"가 여러 번 나와도 모두 변경됩니다.
2. 특정 행 삭제
sed '/DEBUG/d' log.txt
'/DEBUG/d' → "DEBUG"가 포함된 행을 삭제
d → 삭제(delete) 명령어
3. 로그 파일에서 특정 시간대(13시~15시) 로그 삭제
sed '/^2024-02-04 1[3-5]:/d' log.txt
^2024-02-04 1[3-5]: → "2024-02-04 13:xx" ~ "2024-02-04 15:xx" 패턴을 찾습니다.
d → 해당 패턴을 포함한 행 삭제
4. HTML 태그 제거
sed 's/<[^>]*>//g' html.txt
<[^>]*> → <로 시작하고 >로 끝나는 모든 태그를 찾아서 제거
[^>] → >가 아닌 모든 문자
5. 특정 패턴 이후의 모든 텍스트 삭제
sed 's/error.*//g' log.txt
"error" 이후의 모든 내용을 삭제
.* → "error" 뒤의 모든 문자
s/error.*//g → "error"를 포함한 이후 내용을 공백으로 치환
awk를 활용한 정규표현식 필터링
1. 로그에서 특정 필드만 출력
awk '{print $1, $3}' /var/log/syslog
$1 → 첫 번째 필드 출력
$3 → 세 번째 필드 출력
print $1, $3 → 공백을 기준으로 첫 번째와 세 번째 필드를 출력
2. 특정 필드 값이 일정 조건을 만족하는 행만 출력
awk '$3 > 1000' data.txt
$3 > 1000 → 세 번째 필드의 값이 1000보다 큰 행만 출력
3. 특정 IP에서 발생한 요청 개수 카운트
awk '{print $1}' access.log | sort | uniq -c | sort -nr
$1 → 첫 번째 필드(즉, IP 주소)를 추출
sort → 정렬
uniq -c → 중복 개수 카운트
sort -nr → 숫자 내림차순 정렬
4. CSV 파일에서 특정 열만 추출
awk -F, '{print $2, $4}' data.csv
-F, → 구분자를 ,(쉼표)로 지정
$2, $4 → CSV에서 두 번째($2), 네 번째($4) 필드를 출력
5. 특정 문자열을 포함하는 행만 출력
awk '/error/ {print $0}' log.txt
/error/ → "error"가 포함된 행을 찾음
$0 → 현재 행 전체 출력
find를 활용한 정규표현식 필터링
1. 특정 확장자를 가진 파일 찾기
find /var/log -type f -name "*.log"
-type f → 파일만 검색 (디렉터리는 제외)
-name "*.log" → .log로 끝나는 파일 검색
2. 7일 이내 수정된 파일 찾기
find /home/user -type f -mtime -7
-mtime -7 → 최근 7일 이내 수정된 파일 검색
3. 특정 크기 이상의 파일 찾기 (500MB 초과)
find / -size +500M
-size +500M → 500MB보다 큰 파일 검색
4. 특정 문자열을 포함하는 파일 찾기
find /var/log -type f -exec grep "ERROR" {} +
-exec grep "ERROR" {} + → "ERROR"가 포함된 파일을 검색
5. 특정 사용자 소유의 파일 찾기
find /home -type f -user root
-user root → root가 소유한 파일 검색
perl을 활용한 정규표현식 필터링
1. 특정 패턴이 포함된 행 출력
perl -ne 'print if /error/' log.txt
/error/ → "error"가 포함된 행을 출력
2. 로그에서 이메일 주소 추출
perl -nle 'print $& if /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/' emails.txt
[a-zA-Z0-9._%+-]+ → 이메일 사용자명
@ → 고정 문자
[a-zA-Z0-9.-]+ → 도메인명
\.[a-zA-Z]{2,} → .com, .net 같은 도메인 확장자
3. 로그에서 IP 주소 추출
perl -nle 'print $& if /\b\d{1,3}(\.\d{1,3}){3}\b/' access.log
\b\d{1,3}(\.\d{1,3}){3}\b → IPv4 주소 패턴
4. 숫자로만 이루어진 행 출력
perl -ne 'print if /^\d+$/' data.txt
^\d+$ → 숫자로만 이루어진 행을 출력
5. HTML 태그 제거
perl -pe 's/<[^>]*>//g' html.txt
<[^>]*> → <태그> 형태를 찾아 제거
Thanks for watching, Have a nice day.
'IT' 카테고리의 다른 글
grep, linux command 옵션 총정리 (0) | 2025.02.04 |
---|