메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

Linux egrep 명령어 고급

데브카페

egrep 고급 활용 및 관련 명령어

egrep 고급 패턴 매칭

복합 조건 검색

# 날짜 범위 검색 (2023년 12월)
egrep '^2023-12-(0[1-9]|[12][0-9]|3[01])' /var/log/application.log

# 시간대별 필터링 (오전 9시-11시)
egrep ' (09|10|11):[0-5][0-9]:[0-5][0-9] ' /var/log/syslog

# 특정 사용자의 특정 액션
egrep 'user:(admin|root|operator).*action:(login|logout|delete)' audit.log

네트워크 관련 패턴

# MAC 주소 검색
egrep '([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}' network.log

# 포트 번호 (1-65535)
egrep ':([1-9]|[1-9][0-9]|[1-9][0-9]{2}|[1-9][0-9]{3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])' netstat.txt

# 사설 IP 대역
egrep '(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)' network_scan.txt

로그 레벨과 타임스탬프

# Syslog 표준 우선순위
egrep '\[(DEBUG|INFO|NOTICE|WARNING|ERR|CRIT|ALERT|EMERG)\]' system.log

# ISO 8601 날짜 형식
egrep '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?Z?' iso_logs.log

# Apache 로그 날짜 형식
egrep '\[[0-9]{2}/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2} [+-][0-9]{4}\]' apache_access.log

grep 계열 명령어 비교

각 명령어의 특성

명령어 정규식 지원 성능 메모리 사용 적합한 상황
grep BRE (Basic) 보통 낮음 일반적인 검색
egrep ERE (Extended) 보통 중간 복잡한 패턴
fgrep 없음 (문자열만) 매우 빠름 낮음 고정 문자열 대량 검색
pgrep BRE 빠름 낮음 프로세스 이름 검색
zgrep BRE 느림 높음 압축 파일 검색
zegrep ERE 느림 높음 압축 파일 복잡 패턴

실제 성능 비교

#!/bin/bash
# 성능 비교 스크립트

LARGE_FILE="/var/log/huge_log.txt"
TEST_PATTERN="error|warning|critical"

echo "=== 성능 비교 테스트 ==="

# fgrep (가장 빠름 - 단순 문자열)
echo "1. fgrep 테스트:"
time fgrep "error" $LARGE_FILE > /dev/null

# grep -E (egrep과 동일)
echo "2. grep -E 테스트:"
time grep -E $TEST_PATTERN $LARGE_FILE > /dev/null

# egrep 테스트
echo "3. egrep 테스트:"  
time egrep $TEST_PATTERN $LARGE_FILE > /dev/null

# 복잡한 패턴으로 egrep
echo "4. 복잡한 패턴 egrep 테스트:"
time egrep '(error|warning|critical).*(database|connection|timeout)' $LARGE_FILE > /dev/null

zgrep/zegrep 압축 파일 검색

압축 파일 직접 검색

# .gz 파일에서 검색
zgrep 'error' /var/log/syslog.1.gz
zegrep 'error|warning' /var/log/apache2/access.log.*.gz

# .bz2 파일 검색
bzgrep 'pattern' compressed.log.bz2
bzegrep 'error|critical' log_archive.tar.bz2

# .xz 파일 검색  
xzgrep 'pattern' file.log.xz
xzegrep 'error|warning' archive.log.xz

로그 로테이션 파일 일괄 검색

# 현재 + 압축된 로그 모두 검색
{
  egrep 'error' /var/log/application.log
  zegrep 'error' /var/log/application.log.*.gz
} | sort -k1,3

# 스크립트로 자동화
#!/bin/bash
LOG_BASE="/var/log/application.log"
PATTERN="$1"

# 현재 로그
if [ -f "$LOG_BASE" ]; then
    echo "=== Current log ==="
    egrep "$PATTERN" "$LOG_BASE"
fi

# 압축된 과거 로그들
echo "=== Archived logs ==="
for gz_file in ${LOG_BASE}.*.gz; do
    if [ -f "$gz_file" ]; then
        echo "--- $gz_file ---"
        zegrep "$PATTERN" "$gz_file"
    fi
done

정규 표현식 고급 테크닉

Lookahead/Lookbehind (GNU grep 한정)

# Positive lookahead (GNU grep 3.0+에서 제한적 지원)
# 실제로는 Perl이나 Python의 정규식 엔진에서 주로 사용

# 대신 조건부 매칭으로 구현
egrep 'password.*[0-9]' config.txt  # password 뒤에 숫자가 있는 라인

# 복합 조건 체크
egrep '^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).*$' passwords.txt  # (지원 제한적)

문자 클래스 고급 활용

# POSIX 문자 클래스
egrep '[[:alpha:]]+@[[:alnum:].-]+\.[[:alpha:]]{2,}' emails.txt
egrep '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' ips.txt

# 유니코드 지원 (locale 설정 필요)
export LC_ALL=en_US.UTF-8
egrep '[가-힣]+' korean_text.txt    # 한글 검색

# 특수 문자 클래스
egrep '[[:space:]]*error[[:space:]]*' log.txt  # 공백으로 둘러싸인 error
egrep '[[:punct:]]' symbols.txt                # 구두점 문자

대용량 데이터 처리 최적화

메모리 효율적 검색

# mmap 사용으로 메모리 효율성 향상
egrep --mmap 'pattern' huge_file.txt

# 라인 버퍼링으로 실시간 처리
tail -f /var/log/syslog | egrep --line-buffered 'error|warning'

# 병렬 처리
find /var/log -name "*.log" -print0 | \
    xargs -0 -P $(nproc) -I {} egrep -l 'error' {}

분산 검색 전략

#!/bin/bash
# 대용량 로그 분산 검색 스크립트

SEARCH_PATTERN="$1"
LOG_DIR="/var/log"
TEMP_DIR="/tmp/search_$$"
CPU_CORES=$(nproc)

mkdir -p $TEMP_DIR

# 검색할 파일 목록 생성
find $LOG_DIR -name "*.log" -type f > $TEMP_DIR/file_list.txt

# 파일 목록을 CPU 코어 수만큼 분할
split -l $(($(wc -l < $TEMP_DIR/file_list.txt) / $CPU_CORES + 1)) \
    $TEMP_DIR/file_list.txt $TEMP_DIR/chunk_

# 병렬 검색 실행
for chunk in $TEMP_DIR/chunk_*; do
    {
        while read -r file; do
            echo "=== $file ==="
            egrep -n "$SEARCH_PATTERN" "$file" 2>/dev/null
        done < "$chunk"
    } > "$chunk.result" &
done

wait

# 결과 통합
cat $TEMP_DIR/chunk_*.result > search_results.txt
rm -rf $TEMP_DIR

echo "검색 완료: search_results.txt"

로그 분석 전용 스크립트

웹서버 로그 종합 분석기

#!/bin/bash
# 웹서버 로그 종합 분석 스크립트

ACCESS_LOG="/var/log/apache2/access.log"
ERROR_LOG="/var/log/apache2/error.log"
REPORT_FILE="/tmp/web_analysis_$(date +%Y%m%d_%H%M%S).html"

cat > $REPORT_FILE << 'EOF'
<!DOCTYPE html>
<html>
<head><title>웹서버 로그 분석 보고서</title></head>
<body>
<h1>웹서버 로그 분석 보고서</h1>
EOF

# 1. HTTP 상태코드 통계
echo "<h2>HTTP 상태코드 분포</h2><pre>" >> $REPORT_FILE
egrep -o ' [0-9]{3} ' $ACCESS_LOG | sort | uniq -c | sort -nr >> $REPORT_FILE
echo "

" >> $REPORT_FILE

  1. 2. 가장 많이 접근된 페이지

echo "

인기 페이지 TOP 20

" >> $REPORT_FILE
egrep -o '"GET [^"]*"' $ACCESS_LOG | sort | uniq -c | sort -nr | head -20 >> $REPORT_FILE
echo "

" >> $REPORT_FILE

  1. 3. IP 주소별 접근 통계

echo "

IP별 접근 통계 TOP 20

" >> $REPORT_FILE
egrep -o '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' $ACCESS_LOG | \
    sort | uniq -c | sort -nr | head -20 >> $REPORT_FILE
echo "

" >> $REPORT_FILE

  1. 4. 에러 분석

echo "

에러 로그 분석

" >> $REPORT_FILE
if [ -f $ERROR_LOG ]; then
    egrep -i '(error|critical|alert)' $ERROR_LOG | tail -50 >> $REPORT_FILE
fi
echo "

" >> $REPORT_FILE

  1. 5. Bot/Crawler 접근 통계

echo "

Bot/Crawler 접근 통계

" >> $REPORT_FILE
egrep -i '"[^"]*bot[^"]*"|"[^"]*crawler[^"]*"|"[^"]*spider[^"]*"' $ACCESS_LOG | \
    egrep -o '"[^"]*"' | sort | uniq -c | sort -nr >> $REPORT_FILE
echo "

" >> $REPORT_FILE

echo "</body></html>" >> $REPORT_FILE echo "분석 완료: $REPORT_FILE"

시스템 보안 로그 모니터

#!/bin/bash
# 보안 이벤트 모니터링 스크립트

SECURE_LOG="/var/log/secure"
AUTH_LOG="/var/log/auth.log"
ALERT_EMAIL="admin@company.com"

# 1. 무차별 대입 공격 탐지
BRUTE_FORCE=$(egrep "Failed password.*ssh" $SECURE_LOG $AUTH_LOG 2>/dev/null | \
    egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | \
    sort | uniq -c | awk '$1 > 10 {print $2}')

if [ ! -z "$BRUTE_FORCE" ]; then
    echo "경고: SSH 무차별 대입 공격 감지된 IP들:" 
    echo "$BRUTE_FORCE"
    
    # 자동 차단 (선택적)
    # for ip in $BRUTE_FORCE; do
    #     iptables -A INPUT -s $ip -j DROP
    # done
fi

# 2. Root 로그인 모니터링
ROOT_LOGIN=$(egrep "session opened for user root" $SECURE_LOG $AUTH_LOG 2>/dev/null | tail -10)
if [ ! -z "$ROOT_LOGIN" ]; then
    echo "알림: 최근 root 로그인 기록:"
    echo "$ROOT_LOGIN"
fi

# 3. 권한 상승 명령어 모니터링
SUDO_COMMANDS=$(egrep "sudo.*COMMAND" $SECURE_LOG $AUTH_LOG 2>/dev/null | tail -20)
if [ ! -z "$SUDO_COMMANDS" ]; then
    echo "정보: 최근 sudo 명령어 사용 기록:"
    echo "$SUDO_COMMANDS"
fi

# 4. 새로운 사용자 계정 생성 감지
NEW_USERS=$(egrep "new user|new group" $SECURE_LOG $AUTH_LOG 2>/dev/null | tail -10)
if [ ! -z "$NEW_USERS" ]; then
    echo "주의: 새로운 사용자/그룹 생성 감지:"
    echo "$NEW_USERS"
fi

고급 필터링 기법

시간 기반 로그 필터링

#!/bin/bash
# 특정 시간 범위의 로그만 추출

LOG_FILE="$1"
START_TIME="$2"  # 예: "2023-12-01 09:00:00"
END_TIME="$3"    # 예: "2023-12-01 17:00:00"

# ISO 8601 형식 로그의 경우
egrep '^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}' "$LOG_FILE" | \
    awk -v start="$START_TIME" -v end="$END_TIME" \
    '$1 " " $2 >= start && $1 " " $2 <= end {print}'

# syslog 형식의 경우 (더 복잡한 처리 필요)
current_year=$(date +%Y)
egrep "^$(date -d "$START_TIME" '+%b %e %H:%M')" "$LOG_FILE"

멀티라인 로그 처리

# Java 스택 트레이스 같은 멀티라인 로그 처리
egrep -A 10 -B 2 'Exception|Error' application.log

# 트랜잭션 단위로 로그 그룹핑
egrep 'transaction.*start' app.log | while read line; do
    tx_id=$(echo "$line" | egrep -o 'tx_id=[0-9]+')
    echo "=== Transaction: $tx_id ==="
    egrep "$tx_id" app.log
    echo ""
done

성능 튜닝 고급 기법

인덱싱을 활용한 빠른 검색

#!/bin/bash
# 로그 파일 인덱싱 및 빠른 검색 시스템

LOG_FILE="$1"
INDEX_DIR="/tmp/log_index"
mkdir -p $INDEX_DIR

# 1. 날짜별 오프셋 인덱스 생성
awk '{
    date = substr($0, 1, 10)  # YYYY-MM-DD 부분
    if (date != prev_date) {
        if (prev_date != "") {
            print prev_date, prev_offset, NR-1 > "'$INDEX_DIR'/date_index.txt"
        }
        prev_date = date
        prev_offset = NR
    }
} 
END {
    print prev_date, prev_offset, NR > "'$INDEX_DIR'/date_index.txt"
}' "$LOG_FILE"

# 2. 키워드별 라인 번호 인덱스
egrep -n 'error|warning|critical' "$LOG_FILE" | \
    cut -d: -f1 > "$INDEX_DIR/error_lines.txt"

# 3. 빠른 검색 함수
fast_search() {
    local pattern="$1"
    local target_date="$2"
    
    if [ ! -z "$target_date" ]; then
        # 날짜 범위로 제한된 검색
        local line_range=$(awk -v date="$target_date" \
            '$1 == date {print $2 "," $3}' "$INDEX_DIR/date_index.txt")
        
        if [ ! -z "$line_range" ]; then
            sed -n "${line_range}p" "$LOG_FILE" | egrep "$pattern"
        fi
    else
        # 전체 검색
        egrep "$pattern" "$LOG_FILE"
    fi
}

이렇게 egrep의 고급 활용법과 관련 명령어들을 통해 시스템 관리자와 개발자들이 효율적인 로그 분석과 시스템 모니터링을 수행할 수 있습니다.

Comments