以下是關于 sed
(Stream Editor)的深度詳解和日常高頻使用場景,結合實用示例說明:
一、sed 核心概念
- 流式編輯器:逐行處理文本,不直接修改源文件(除非使用
-i
選項) - 正則支持:基礎正則(BRE)和擴展正則(ERE,需加
-r
或-E
) - 核心原理:讀取 → 模式匹配 → 執行命令 → 輸出
二、基礎語法格式
sed [選項] '地址范圍/命令/參數' 文件
三、高頻使用場景與示例
1. 文本替換
# 替換每行第一個匹配項
sed 's/old/new/' file.txt# 全局替換(所有匹配項)
sed 's/old/new/g' file.txt# 替換第N次出現的匹配
sed 's/old/new/2' file.txt # 只替換每行第二個匹配# 替換時忽略大小寫(GNU sed擴展)
sed 's/old/new/i' file.txt
2. 刪除行
# 刪除空行
sed '/^$/d' file.txt# 刪除注釋行(以#開頭)
sed '/^#/d' config.conf# 刪除特定范圍行
sed '10,20d' file.txt # 刪除10-20行
sed '/start/,/end/d' file.txt # 刪除兩個模式間的行
3. 插入/追加行
# 在第3行前插入文本
sed '3i\插入的內容' file.txt# 在匹配行后追加
sed '/pattern/a\追加的內容' file.txt# 文件開頭/結尾插入
sed '1i\開頭內容' file.txt
sed '$a\結尾內容' file.txt
4. 行篩選打印
# 打印含"error"的行(類似grep)
sed -n '/error/p' log.txt# 打印行號范圍
sed -n '10,15p' file.txt# 打印奇數行
sed -n '1~2p' file.txt # 1,3,5...
5. 文件原地修改
# 直接修改文件(先測試!)
sed -i.bak 's/old/new/g' file.txt # 備份原文件為file.txt.bak
sed -i '' 's/old/new/g' file.txt # macOS下無備份修改
6. 高級替換技巧
# 引用匹配內容
echo "123 abc" | sed 's/[0-9]\+/[&]/' # 輸出 "[123] abc"# 分組捕獲(使用\1,\2引用)
echo "foo-bar" | sed 's/\(foo\)-\(bar\)/\2-\1/' # 輸出 "bar-foo"# 條件替換(僅對匹配行操作)
sed '/warning/s/foo/bar/' log.txt # 只在含"warning"的行替換foo
7. 多命令組合
# 用分號分隔多個命令
sed 's/foo/bar/g; s/baz/qux/g' file.txt# 或用-e選項
sed -e 's/foo/bar/' -e '/baz/d' file.txt
四、日常實用案例
1. 日志處理
# 提取時間戳和錯誤信息
sed -n '/ERROR/{s/.*\(202[0-9]-[0-9]\{2\}-[0-9]\{2\}\).*\(ERROR:.*\)/\1 \2/p}' app.log# 統計HTTP狀態碼
sed -n 's/.*HTTP\/1\.[01]" \([0-9]\{3\}\).*/\1/p' access.log | sort | uniq -c
2. 配置文件修改
# 注釋掉某配置項
sed -i '/^SELINUX=/s/^/#/' /etc/selinux/config# 修改鍵值對
sed -i 's/^\(PORT=\).*/\13306/' config.ini
3. 數據清洗
# CSV轉TSV
sed 's/,/\t/g' data.csv# 刪除HTML標簽
sed 's/<[^>]*>//g' page.html
4. 批量重命名
# 測試重命名命令
ls *.jpg | sed 's/\(.*\)\.jpg/mv & \1_backup.jpg/'# 實際執行(先確認輸出無誤)
ls *.jpg | sed 's/\(.*\)\.jpg/mv & \1_backup.jpg/' | bash
5. 代碼處理
# 縮進所有行(前加4空格)
sed 's/^/ /' source.py# 刪除行尾空格
sed 's/[[:space:]]*$//' file.txt
五、sed 調試技巧
- 先不加
-i
:測試時輸出到屏幕確認效果sed 's/pattern/replace/' file.txt
- 打印處理的行:
sed -n 's/foo/bar/p' file.txt # 只顯示被修改的行
- 使用
&
調試:sed 's/pattern/& ==> replaced/' file.txt # 標記被替換的內容
六、性能優化建議
- 合并多個操作:減少管道和多次讀取
# 低效 cat file | sed 's/foo/bar/' | sed '/baz/d' # 高效 sed -e 's/foo/bar/' -e '/baz/d' file
- 限制處理范圍:用地址范圍減少處理行數
sed '100,200s/foo/bar/' largefile.txt
掌握這些 sed
技巧后,90% 的日常文本處理任務都能高效完成。對于更復雜的需求(如跨行處理),可結合 awk
或 perl
。