Linux 文本處理三劍客:awk、grep、sed 完全指南
1. 概述
Linux 系統提供了三個強大的文本處理工具:awk、grep 和 sed,它們各有所長,結合使用可以高效地處理文本數據。
- awk:擅長文本分析和格式化輸出,是一門強大的腳本語言。
- grep:擅長文本搜索和過濾。
- sed:擅長文本編輯和轉換。
這三個工具都支持正則表達式,可以處理標準輸入和文件輸入,是 Shell 腳本編程中不可或缺的工具。
2. awk 使用指南
2.1 基本介紹
awk 是一種編程語言,專門用于文本處理和數據提取,支持變量、條件判斷、循環等編程特性。其名稱來源于三位創始人的姓氏首字母。
2.2 基本語法
awk '模式 { 動作 }' [輸入文件...]
命令 | awk '模式 { 動作 }'
2.3 工作原理
awk 按行處理文本,每行被分割成多個字段:
$0
:整行內容$1
:第一個字段$2
:第二個字段- …
2.4 常用選項
選項 | 說明 | 示例 |
---|---|---|
-F | 指定輸入字段分隔符 | awk -F: '{print $1}' /etc/passwd |
-v | 定義變量 | awk -v var=10 '{print $1 + var}' file |
-f | 從腳本文件中讀取 awk 命令 | awk -f script.awk data.txt |
2.5 內置變量
變量 | 說明 | 示例 |
---|---|---|
FS | 輸入字段分隔符(默認空格) | awk 'BEGIN{FS=":"}{print $1}' file |
OFS | 輸出字段分隔符(默認空格) | awk 'BEGIN{OFS="-"}{print $1,$2}' file |
RS | 輸入記錄分隔符(默認換行符) | awk 'BEGIN{RS=";"}{print}' file |
ORS | 輸出記錄分隔符(默認換行符) | awk 'BEGIN{ORS="\n\n"}{print}' file |
NF | 當前行的字段數量 | awk '{if(NF>5) print $0}' file |
NR | 當前處理的總行號 | awk '{print NR, $0}' file |
FNR | 當前文件中的行號 | awk '{print FNR, $0}' file1 file2 |
FILENAME | 當前文件名 | awk '{print FILENAME, $0}' file |
2.6 示例
# 打印指定列(源文檔示例)
awk '{print $1, $3}' file.txt# 指定分隔符(源文檔示例)
awk -F: '{print $1, $6}' /etc/passwd# 使用條件過濾(源文檔示例)
awk '$3 > 1000 {print $1}' /etc/passwd# 計算數值總和(源文檔示例)
awk '{sum += $1} END {print sum}' file.txt# 使用BEGIN和END塊(源文檔示例)
awk 'BEGIN {print "開始處理"} {print $0} END {print "處理完成"}' file.txt# 使用內置變量(源文檔示例)
awk '{print "行號:", NR, "字段數:", NF, "內容:", $0}' file.txt# 打印雇員信息(源文檔示例)
awk '{ print }' employee.txt# 輸出特定行(源文檔示例)
awk '/張三/ { print }' employee.txt# 統計滿足特定條件的記錄數(源文檔示例)
awk '/術/ { count=count+1 } END { print "Count="count }' employee.txt# 格式化輸出表格(源文檔綜合示例)
awk 'BEGIN { printf "序號\t名字\t部門\t年齡\n-------------------\n" } { print } END {printf "-------------------\n"}' employee.txt
2.7 高級用法
# 使用數組統計詞頻(源文檔示例)
awk '{for(i=1;i<=NF;i++) count[$i]++} END {for(word in count) print word, count[word]}' file.txt | sort -k2 -nr# 條件判斷(源文檔示例)
awk '{if($3 > 1000) print "用戶:", $1, "UID:", $3; else print "系統用戶:", $1}' /etc/passwd# 循環處理(源文檔示例)
awk '{for(i=NF;i>=1;i--) printf "%s ", $i; printf "\n"}' file.txt# 9x9乘法表(源文檔示例)
awk 'BEGIN {for(i=1;i<=9;i++){for(j=1;j<=i;j++) printf "%d*%d=%-2d ",j,i,j*i; print}}'
3. grep 使用指南
3.1 基本介紹
grep (Global Regular Expression Print) 用于在文本中搜索匹配指定模式的行。
3.2 基本語法
grep [選項] 模式 [文件...]
命令 | grep [選項] 模式
3.3 常用選項
選項 | 說明 | 示例 |
---|---|---|
-i | 忽略大小寫 | grep -i 'hello' file.txt |
-v | 反向匹配,顯示不匹配的行 | grep -v '^#' config.conf |
-n | 顯示行號 | grep -n 'error' logfile.txt |
-c | 只顯示匹配的行數 | grep -c 'pattern' data.txt |
-r | 遞歸搜索目錄 | grep -r 'function' /path/to/code/ |
-l | 只顯示包含匹配的文件名 | grep -l 'TODO' *.py |
-E | 使用擴展正則表達式 | `grep -E '(error |
-A n | 顯示匹配行及其后n行 | grep -A 3 'Exception' traceback.log |
-B n | 顯示匹配行及其前n行 | grep -B 2 'segmentation fault' system.log |
-C n | 顯示匹配行及其前后各n行 | grep -C 2 'keyword' file.txt |
3.4 示例
# 搜索包含"error"的行(源文檔示例)
grep 'error' logfile.txt# 忽略大小寫搜索(源文檔示例)
grep -i 'error' logfile.txt# 顯示行號(源文檔示例)
grep -n 'error' logfile.txt# 搜索并顯示后3行內容(源文檔示例)
grep -A 3 'error' logfile.txt# 遞歸搜索目錄(源文檔示例)
grep -r 'function' /path/to/code/# 使用擴展正則表達式(源文檔示例)
grep -E '(error|warning)' logfile.txt# 統計文件中包含特定模式的記錄數(源文檔awk示例的grep等效)
grep -c 'pattern' employee.txt# 輸出總長度大于10的行(源文檔awk示例的grep等效)
grep '.\{11,\}' employee.txt
4. sed 使用指南
4.1 基本介紹
sed (Stream EDitor) 是一個流編輯器,用于對文本進行非交互式的編輯。
4.2 基本語法
sed [選項] '命令' [輸入文件...]
命令 | sed [選項] '命令'
4.3 常用選項
選項 | 說明 | 示例 | |
---|---|---|---|
-n | 抑制自動輸出,只顯示處理過的行 | sed -n '10p' file.txt | |
-e | 允許多個編輯命令 | sed -e 's/foo/bar/' -e '/baz/d' file | |
-i | 直接修改文件內容 | sed -i.bak 's/old/new/g' file.txt | |
-r | 使用擴展正則表達式 | `sed -r 's/(foo | bar)/YES/g’ file` |
4.4 常用命令
命令 | 說明 | 示例 |
---|---|---|
s/模式/替換/標志 | 替換操作 | sed 's/old/new/g' file.txt |
p | 打印 | sed -n '1,5p' file.txt |
d | 刪除 | sed '/pattern/d' file.txt |
a\文本 | 在行后追加文本 | sed '$a\追加到最后一行' file.txt |
i\文本 | 在行前插入文本 | sed '1i\插入到第一行' file.txt |
c\文本 | 替換整行 | sed '/pattern/c\新的整行內容' file.txt |
4.5 示例
# 替換文本(源文檔示例)
sed 's/old/new/g' file.txt# 刪除空行(源文檔示例)
sed '/^$/d' file.txt# 直接修改文件(源文檔示例)
sed -i 's/old/new/g' file.txt# 打印特定行(源文檔示例)
sed -n '10,20p' file.txt# 多重編輯(源文檔示例)
sed -e 's/foo/bar/g' -e '/baz/d' file.txt# 在匹配行后追加內容(源文檔示例)
sed '/pattern/a\追加的內容' file.txt# 模擬cat命令打印文件內容(源文檔示例)
sed '' data.txt# 從標準輸入中讀取數據(源文檔示例)
echo "hello world" | sed ''# 使用腳本文件(源文檔示例)
echo -e "1d\n2d\n5d" > scripts
sed -f scripts data.txt
5. 綜合應用示例
5.1 日志分析
# 分析日志中的錯誤,統計每種錯誤的數量(源文檔grep示例擴展)
grep 'ERROR' application.log | awk '{print $5}' | sort | uniq -c | sort -nr# 提取最近一小時的日志并分析(源文檔sed示例擴展)
sed -n "/$(date -d '1 hour ago' '+%H:%M:%S')/,\$p" application.log | grep 'ERROR' | awk '{print $5}' | sort | uniq -c
5.2 數據提取和轉換
# 從CSV文件中提取特定列并轉換格式(源文檔awk示例擴展)
awk -F, '{print $1 "," $3 "," $5}' data.csv | sed 's/舊值/新值/g' > processed_data.csv# 提取網頁中的鏈接(源文檔grep示例擴展)
curl -s http://example.com | grep -o 'href="[^"]*"' | sed 's/href="//;s/"$//' | awk '!/^#/ && !/^javascript:/'# 生成格式化的文本報告(源文檔awk綜合示例擴展)
awk 'BEGIN {printf "序號\t名字\t部門\t年齡\n-------------------\n"} {printf "%s\t%s\t%s\t%s\n", $1, $2, $3, $4} END {printf "-------------------\n"}' employee.txt
5.3 系統監控
# 監控進程內存使用(源文檔awk示例擴展)
ps aux | awk '{if($4 > 5.0) print "進程:", $11, "內存使用:", $4"%"}'# 分析磁盤使用情況(源文檔awk示例擴展)
df -h | awk '/\/dev\/sd/ {print "分區:", $1, "使用率:", $5, "可用空間:", $4}'# 檢查系統用戶(源文檔awk示例擴展)
awk -F: '$3 < 1000 {print "系統用戶:", $1} $3 >= 1000 {print "普通用戶:", $1}' /etc/passwd
6. 正則表達式參考
6.1 基本元字符
元字符 | 說明 |
---|---|
. | 匹配任意單個字符 |
* | 匹配前一個字符0次或多次 |
+ | 匹配前一個字符1次或多次 |
? | 匹配前一個字符0次或1次 |
^ | 匹配行首 |
$ | 匹配行尾 |
[] | 匹配括號內的任意字符 |
[^] | 不匹配括號內的任意字符 |
` | ` |
() | 分組 |
6.2 字符類
字符類 | 說明 |
---|---|
[[:alpha:]] | 字母字符 |
[[:digit:]] | 數字字符 |
[[:alnum:]] | 字母數字字符 |
[[:space:]] | 空白字符 |
[[:lower:]] | 小寫字母 |
[[:upper:]] | 大寫字母 |
6.3 轉義字符
轉義序列 | 說明 |
---|---|
\n | 換行符 |
\t | 制表符 |
\s | 空白字符 |
\S | 非空白字符 |
\w | 單詞字符 |
\W | 非單詞字符 |
\d | 數字字符 |
\D | 非數字字符 |
7. 總結與速查
7.1 工具選擇指南
- 搜索文本:使用 grep
- 編輯文本:使用 sed
- 處理結構化數據:使用 awk
- 復雜文本處理:結合使用三者
7.2 常用命令速查
awk 常用命令
awk '{print $1}' file # 打印第一列
awk -F: '{print $1}' file # 指定冒號分隔符并打印第一列
awk 'NR==10' file # 打印第10行
awk '$1 > 100' file # 過濾第一列大于100的行
awk '{sum+=$1} END{print sum}' file # 對第一列求和
awk 'BEGIN{FS=":";OFS="-"}{print $1,$3}' file # 設置輸入輸出分隔符并打印
awk '/pattern/{count++} END{print count}' file # 統計模式出現次數
grep 常用命令
grep pattern file # 基本搜索
grep -i pattern file # 忽略大小寫
grep -v pattern file # 反向匹配
grep -n pattern file # 顯示行號
grep -r pattern dir # 遞歸搜索
grep -E "pattern1|pattern2" file # 擴展正則表達式(或)
grep -c pattern file # 統計匹配行數
grep -A n pattern file # 顯示匹配行及后n行
sed 常用命令
sed 's/old/new/g' file # 全局替換
sed '/pattern/d' file # 刪除匹配行
sed -n '10,20p' file # 打印10-20行
sed -i.bak 's/old/new/' file # 直接修改文件并備份原文件
sed '/^#/d; /^$/d' file # 刪除注釋和空行
sed '1,5s/old/new/g' file # 替換1-5行的內容
sed '/pattern/a\text' file # 在匹配行后追加文本
7.3 性能優化技巧
- 盡量使用最簡單的正則表達式
- 在 grep 中使用
-F
選項處理固定字符串 - 在 awk 中預先處理數據減少后續操作
- 使用管道連接多個簡單操作而不是一個復雜操作
- 對于大文件,考慮使用
split
分割后并行處理
7.4 常見問題解決
- 特殊字符處理:使用轉義字符或不同的定界符(如
s#old#new#
) - 跨行匹配:使用 sed 的
N
、D
命令或 awk 的RS
變量 - 性能問題:優化正則表達式,減少回溯
- 編碼問題:確保終端和文件編碼一致
通過掌握這三款工具的組合使用,可以解決 Linux 環境下絕大多數文本處理需求,大大提高工作效率。本文檔涵蓋了源文檔中的主要示例和用法,并添加了選項示例,可以作為日常參考和學習的指南。