| 流派 | 代表工具 | 特殊字符差異 | 典型場景 |
|---|---|---|---|
| BRE (Basic) | grep, sed | \+ \? \{n\} \(\) 需轉義 | 簡單行匹配、流編輯 |
| ERE (Extended) | egrep/grep -E, awk | + ? {n} () 免轉義 | 複雜模式、邏輯或、分組 |
| PCRE (Perl) | grep -P, perl, python | 最豐富:\d \w (?=) (?!) 等 | 高級提取、零寬斷言 |
| 字符 | BRE | ERE/PCRE | 含義 | 示例匹配 |
|---|---|---|---|---|
^ | ✓ | ✓ | 行首 | ^root 匹配以 root 開頭的行 |
$ | ✓ | ✓ | 行尾 | bash$ 匹配以 bash 結尾的行 |
. | ✓ | ✓ | 任意單字符(除換行符) | c.t 匹配 cat, cut, czt |
* | ✓ | ✓ | 前一字符 0~n 次 | ab*c 匹配 ac, abc, abbc, abbbc |
\+ / + | 轉義 | 免轉義 | 前一字符 1~n 次 | ab+c 匹配 abc, abbc... |
\? / ? | 轉義 | 免轉義 | 前一字符 0~1 次 | ab?c 匹配 ac, abc |
\{n,m\} / {n,m} | 轉義 | 免轉義 | 前一字符 n~m 次 | a\{2,4\} 匹配 aa, aaa, aaaa |
[] | ✓ | ✓ | 字符集合 | [aeiou] 匹配任一元音 |
[^] | ✓ | ✓ | 排除字符集 | [^0-9] 匹配非數字 |
\| / | | 轉義 | 免轉義 | 邏輯或 | cat|dog 匹配 cat 或 dog |
\(\) / () | 轉義 | 免轉義 | 分組捕獲 | (ab)+ 匹配 ab, abab... |
\1 / \1 | ✓ | ✓ | 反向引用第 1 組 | (word) \1 匹配 word word |
\b | ✗ | PCRE | 單詞邊界 | \bcat\b 單詞 cat |
\d \w \s | ✗ | PCRE | 數字/單詞字符/空白 | \d{3}-\d{8} 電話號碼 |
# 搜索單文件
grep 'error' /var/log/messages
# 遞歸搜索目錄
grep -r 'TODO' /home/user/project/
# 忽略大小寫
grep -i 'warning' *.log
# 顯示行號
grep -n 'pattern' file
# 只輸出匹配部分
grep -o 'pattern' file
# 反向匹配(不含)
grep -v '^#' config.conf # 排除註釋行
# 統計匹配行數
grep -c 'pattern' file
# ERE 模式(推薦複雜正則)
grep -E '^(error|warn|fatal)' /var/log/app.log
# PCRE 模式(最強)
grep -P '(?<=user=)\w+' access.log # 正向後顧:提取 user= 後的單詞
grep -P '\d{1,3}(\.\d{1,3}){3}' access.log # IPv4 地址
# 固定字符串(快,無正則解析)
grep -F 'literal.string' file
# 查找進程(排除 grep 自身)
ps aux | grep '[s]shd'
# 提取 IP 地址
grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' access.log | sort -u
# 統計錯誤碼分布
grep -oE 'HTTP/[0-9.]+" [0-9]{3}' access.log | awk '{print $2}' | sort | uniq -c | sort -nr
# 多文件搜索只顯示文件名
grep -l 'pattern' *.conf
sed [選項] '腳本' 文件
sed -f script.sed 文件
| 命令 | 作用 | 示例 |
|---|---|---|
s/舊/新/ | 替換(首次) | sed 's/old/new/' file |
s/舊/新/g | 全局替換 | sed 's/old/new/g' file |
s/舊/新/gi | 忽略大小寫全局替換 | sed 's/old/new/gi' file |
d | 刪除行 | sed '/^#/d' file 刪除註釋行 |
p | 打印(配合 -n) | sed -n '/error/p' file 只打印含 error 的行 |
a\文本 | 行後追加 | sed '/^#/a\new line' file |
i\文本 | 行前插入 | sed '1i\header' file |
c\文本 | 整行替換 | sed '/pattern/c\new line' file |
y/源/目標/ | 字符轉換 | sed 'y/abc/ABC/' file |
# 1. 在文件第 3 行插入內容
sed -i '3i\New line inserted' file
# 2. 刪除空行及純空白行
sed -i '/^[[:space:]]*$/d' file
# 3. 替換配置文件鍵值
sed -i 's/^\(max_connections\s*=\s*\).*/\11000/' my.cnf
# 4. 提取 JSON 中的字段(簡易)
sed -n 's/.*"name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' data.json
# 5. 多條腳本組合
sed -e 's/foo/bar/g' -e '/^$/d' -e 's/#.*//' file
RS 控制)FS/-F 控制)NR 行號、NF 字段數、$0 整行、$1-$n 字段awk '模式 {動作}' 文件
awk -F: '模式 {動作}' 文件 # 指定分隔符
# 1. 打印 /etc/passwd 用戶名和 Shell
awk -F: '{print $1, $7}' /etc/passwd
# 2. 計算文件大小總和(ls -l 輸出)
ls -l | awk '{sum+=$5} END {print sum, "bytes"}'
# 3. 過濾大於 100M 的文件
ls -l | awk '$5 > 104857600 {print $9, $5/1024/1024 "MB"}'
# 4. 統計日志中各 HTTP 狀態碼次數
awk '{print $9}' access.log | sort | uniq -c | sort -nr
# 或純 awk:
awk '{code[$9]++} END {for(c in code) print c, code[c]}' access.log
# 5. 多文件合併去重(保留首次出現)
awk '!seen[$0]++' file1 file2 > merged
# 6. 處理 CSV(含引號逗號)
awk -F',' '{for(i=1;i<=NF;i++) gsub(/^"|"$/, "", $i); print $1, $3}' data.csv
# NR==FNR 技巧:先讀文件 1 建立字典,再處理文件 2
awk 'NR==FNR {dict[$1]=$2; next} $1 in dict {print $0, dict[$1]}' dict.txt data.txt
diff -u old new > changes.patch # 統一格式(推薦)
diff -uNr old_dir new_dir > dir.patch # 目錄遞歸比較
diff -y file1 file2 # 並排顯示
patch -p1 < changes.patch # 應用補丁
patch -p1 --dry-run < changes.patch # 僅預覽
patch -R -p1 < changes.patch # 回滾補丁
grep -E/awk),少轉義,可讀性強grep -P/perl),善用零寬斷言'pattern' 防 Shell 展開grep | sed | awk | sort | uniq 管道流#!/bin/bash
# 生成測試日志
cat > /tmp/test.log <<'EOF'
2023-01-01 10:00:00 INFO User login user=alice ip=192.168.1.1
2023-01-01 10:01:00 ERROR DB connect failed user=bob ip=192.168.1.2
2023-01-01 10:02:00 WARN Slow query user=alice ip=192.168.1.1 sql="SELECT * FROM t"
2023-01-01 10:03:00 INFO User logout user=alice
EOF
echo "=== grep -P 提取 user ==="
grep -oP '(?<=user=)\w+' /tmp/test.log | sort -u
echo "=== awk 統計用戶操作次數 ==="
awk '{for(i=1;i<=NF;i++) if($i~/^user=/) split($i,a,"="); cnt[a[2]]++} END{for(u in cnt) print u, cnt[u]}' /tmp/test.log
echo "=== sed 格式化輸出 ==="
sed -E 's/^(.*?) (INFO|ERROR|WARN) (.*)$/[\2] \1 -> \3/' /tmp/test.log
Linux 文本處理三劍客 grep(找)、sed(改)、awk(算) 配合正則表達式,能解決 95% 的日志分析、配置修改、數據提取需求。關鍵在於:
'pattern' 引號習慣熟練掌握這些工具,是 Linux 用戶從「會用命令」進化為「數據處理專家」的分水嶺。
Linux 磁碟空間暴增排查實戰:du 指令快速定位佔用空間大戶
Quartz Cron 表達式完整教學:常用排程範例與語法詳解
Linux SUID/SGID/Sticky 位深度解析:權限模型、安全風險與查找實戰
Linux 開機啟動腳本機制深度解析:init、runlevel、rc.d 目錄結構與自定義服務排序
Git 推送錯誤 "git did not exit cleanly (exit code 128)" 解決:Bitbucket 團隊成員超過 5 人限制
Linux 磁碟空間分析實戰:df 與 du 指令進階用法與差異解析