Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 正則表達式與 grep/sed/awk 文本處理實戰大全

編輯:Linux 教學

一、正則表達式基礎:三大流派差異

流派代表工具特殊字符差異典型場景
BRE (Basic)grep, sed\+ \? \{n\} \(\) 需轉義簡單行匹配、流編輯
ERE (Extended)egrep/grep -E, awk+ ? {n} () 免轉義複雜模式、邏輯或、分組
PCRE (Perl)grep -P, perl, python最豐富:\d \w (?=) (?!) 等高級提取、零寬斷言

二、核心元字符速查表

字符BREERE/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 族命令實戰

1. 基礎用法

# 搜索單文件
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

2. 正則進階

# 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

3. 經典組合拳

# 查找進程(排除 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 [選項] '腳本' 文件
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

五、awk 模式掃描與處理語言:列級處理王者

核心概念

  • 記錄:默認一行(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/patch:文件差異與補丁

diff 常用參數

diff -u old new > changes.patch    # 統一格式(推薦)
diff -uNr old_dir new_dir > dir.patch  # 目錄遞歸比較
diff -y file1 file2                # 並排顯示

patch 應用補丁

patch -p1 < changes.patch          # 應用補丁
patch -p1 --dry-run < changes.patch # 僅預覽
patch -R -p1 < changes.patch       # 回滾補丁

七、正則表達式最佳實踐

  1. 默認用 ERE(grep -E/awk),少轉義,可讀性強
  2. 複雜提取用 PCRE(grep -P/perl),善用零寬斷言
  3. 固定字符串用 -F,速度快數量級
  4. 模式兩端加引號:'pattern' 防 Shell 展開
  5. 整行處理思維:grep/sed/awk 默認按行處理,跨行需特殊技巧
  6. 組合拳優於單工具: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% 的日志分析、配置修改、數據提取需求。關鍵在於:

  • 選對正則流派(BRE/ERE/PCRE)
  • 理解行處理與列處理的邊界
  • 善用管道組合而非寫大腳本
  • 養成 'pattern' 引號習慣

熟練掌握這些工具,是 Linux 用戶從「會用命令」進化為「數據處理專家」的分水嶺。

Copyright © Windows教程網 All Rights Reserved