Unix/Linux 的 sed 指令使用
sed 和 awk 都是 Linux 中常用的字串處理,awk 注重於欄位分割處理,sed 則是注重在文字的替換。可以理解為搜尋功能比較弱且著重於字串修改的 grep。
一樣請出 Claude 3.7 寫教學,並且使用和 awk 教學 一樣的範例文本。
📘 基礎篇
什麼是 sed
sed (Stream EDitor) 是一款強大的文字處理工具,它可以對文字流進行編輯,常用於文本替換、過濾和轉換。sed 並不直接修改原始檔案,而是將處理後的結果輸出到標準輸出,這使得它特別適合搭配其他 Unix 指令來使用。它的設計理念是處理文字串流,因此每次從輸入讀取一行,處理後輸出,再處理下一行。
基本語法結構
sed 指令的基本格式如下:
sed [選項] '指令' 檔案
常用選項包括:
-n
:不輸出模式空間內容,除非明確要求輸出-e
:允許多個編輯指令-i
:直接修改原始檔案-r
或-E
:使用擴展正則表達式
指令格式通常為:[地址範圍]/指令/[標誌]
,例如:
# 顯示 log.txt 檔案中所有內容(相當於 cat)
sed '' log.txt
# 只顯示第一行
sed -n '1p' log.txt
文本替換
替換指令 s
是 sed 最常使用的指令,語法為:s/原始文本/替換文本/[標誌]
:
# 將日誌中的 GET 替換為 [GET]
sed 's/GET/[GET]/' log.txt
# 將第一行的 HTTP/1.1 替換為 HTTP/2
sed '1s|HTTP/1\.1|HTTP/2|g' log.txt
# 將第一行的 HTTP/1.1 替換為 HTTP/2,並且寫回,BSD 版本需要加上 ''
sed -i '' '1s|HTTP/1\.1|HTTP/2|g' log.txt
# 使用 g 標誌替換該行所有匹配項
sed 's/Mozilla/Chrome/g' log.txt
替換指令常用標誌:
g
:全局替換(預設只替換每行第一個匹配項)p
:配合-n
選項,只印出有替換的行i
:不區分大小寫
基本正則表達式符號
sed 支援基本正則表達式
# 找出包含 POST 的行
sed -n '/POST/p' log.txt
# 找出以 192.168 開頭的行
sed -n '/^192\.168/p' log.txt
# 找出以 +0000 結尾的行(注:實際日誌中可能包含引號和其他字元)
sed -n '/\+0000]/p' log.txt
行範圍選擇
sed 可以通過數字、正則表達式或兩者組合來指定處理範圍:
# 只處理第 3 行
sed -n '3p' log.txt
# 處理第 2 到第 4 行
sed -n '2,4p' log.txt
# 處理包含 "john" 的行
sed -n '/john/p' log.txt
# 處理從包含 "john" 到包含 "alice" 的行
sed -n '/john/,/alice/p' log.txt
輸出控制
sed 提供多種輸出控制指令:
p
:輸出當前模式空間的內容d
:刪除模式空間的內容,不輸出q
:退出 sed 處理
# 只顯示包含 Mozilla 的行
sed -n '/Mozilla/p' log.txt
# 刪除包含 Mozilla 的行
sed '/Mozilla/d' log.txt
# 顯示到第 3 行就退出
sed '3q' log.txt
# 刪除空行
sed '/^$/d' log.txt
通過這些基礎功能,我們可以實現許多簡單的文本處理任務。在 nginx 日誌處理上,這些指令已經能夠幫助我們提取和格式化我們需要的資訊,例如統計特定 IP 訪問、提取特定請求方法等。
📘 中階篇
sed 與其他命令整合
sed 可以與 Unix 管道符號 (|
) 結合使用,實現更複雜的處理流程:
# 先用 grep 過濾出 POST 請求 ,再用 sed 提取 URL 部分
grep "POST" log.txt | sed 's/.*"POST \([^ ]*\).*/\1/'
# 計算各種 HTTP 請求的數量
sed -n 's/.*"\([A-Z]*\) .*/\1/p' log.txt | sort | uniq -c
# 結合 awk 提取 IP 和請求方法
sed -n 's/\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*"\([A-Z]*\) .*/\1 \2/p' log.txt | awk '{print $2 " from " $1}'
管道符號能將一個命令的輸出連接到另一個命令的輸入,使我們能夠將複雜任務分解為更簡單的步驟。結合 grep
、awk
、sort
等工具,sed 的功能可以得到極大的擴展。