Linux 三劍客之 sed:90% 的人只會替換文本,你錯過了多少神技?
前言:改個文件還得手動?試試 sed,一秒搞定!
大家好,我是小康。
還在手動修改配置文件?日志分析時翻半天找關鍵詞?批量替換文本還得一個個點開改?
別折騰了!今天就帶你認識 Linux 里的“文本處理神器”——sed,讓你用一行命令,批量修改、刪除、替換文本內容,輕松搞定以前要手動改半天的事!
用 sed 能干什么?
- 批量修改文本 ?? 比如,把 hello 全部改成 hi
- 刪除特定行 ?? 比如,刪掉文件里的第 10 行
- 提取特定內容 ?? 比如,只顯示文件里的第 5 到 10 行
- 日志分析 ?? 過濾掉無關信息,只顯示你關心的部分
sed 很強大,很多 Linux 高手天天都在用,但很多人還不知道它的威力。今天,我們就來聊聊 sed,只講 最常用的命令,不搞復雜難懂的東西,讓你 看完就能用,學完就能上手!
一、sed 是什么?為什么你一定要學會它?
sed 簡單介紹
sed,全稱 Stream Editor(流編輯器),它的核心思想是:
不打開文件,直接在命令行中修改、刪除、替換文本,并且可以把修改后的結果輸出到終端或保存到文件。
換句話說,它不像 vim、nano 那樣需要手動編輯文件,而是 自動化處理文本,適合處理日志、批量修改文件、數據提取等場景。
基礎用法:
sed '指令' 文件
這個 指令 就是告訴 sed 你想干嘛,比如 替換、刪除、顯示某些行。
二、sed 最常用的 6 個操作
光講概念沒意思,直接上實戰,不看廢話,看完就會!
1. 替換文本(相當于 Ctrl+H)
用法:
sed 's/舊內容/新內容/' 文件名
- s:表示 substitute(替換)
- /舊內容/新內容/:表示 將“舊內容”替換成“新內容”
?? 示例:把 hello 替換成 hi
echo "hello world" | sed 's/hello/hi/'
輸出:
hi world
在文件里替換:
假設 file.txt 里有:
hello Alice,hello Alice's sister
hello Bob, hello Bob's brother
hello Charlie
執行:
sed 's/hello/hi/' file.txt
輸出:
hi Alice,hello Alice's sister
hi Bob, hello Bob's brother
hi Charlie
- 這里只是打印出修改后的結果,但不會真正修改 file.txt 的內容。
- 你只是看到終端里 hello 被替換成了 hi,但 file.txt本身沒有發生任何變化。
你可以用 cat file.txt 再看一遍文件內容,會發現它還是原來的樣子。
問題:怎么只替換了每一行第一個出現的 hello?怎么全部替換 ?如果我想改文件,又該怎么做? ?? ,繼續往下看。
2. 全局替換(所有匹配項都替換)
默認情況下,sed只替換每一行的第一個匹配項,如果想替換所有,要加 g(global):
sed 's/hello/hi/g' file.txt
輸出:
hi Alice,hi Alice's sister
hi Bob, hi Bob's brother
hi Charlie
記住 g,否則只會替換每行的第一個匹配項!
3. 直接修改文件
默認 sed 不會改動原文件,只是把修改結果輸出到終端。如果想真正改文件,需要加 -i:
sed -i 's/hello/hi/g' file.txt
注意:
- -i直接修改文件,沒有撤銷功能,誤操作可能會導致數據丟失!
- 建議先使用 cat file.txt 看看內容,確保不會誤改重要文件。
更安全的方式:先備份文件,再修改!
為了避免誤操作導致數據丟失,推薦使用 -i.bak先創建文件備份,然后再修改:
sed -i.bak 's/hello/hi/g' file.txt
執行后,系統會:
- 修改 file.txt,將 hello 替換成 hi。
- 自動創建 file.txt.bak 備份文件(修改前的內容)。
示例:
假設 file.txt 內容如下:
hello world
hello Linux
hello sed
執行:
sed -i.bak 's/hello/hi/g' file.txt
執行后:
- file.txt 被修改:
hi world
hi Linux
hi sed
- file.txt.bak 是原始文件的備份(未修改的內容):
hello world
hello Linux
hello sed
如何恢復原文件?
如果修改后發現有問題,可以隨時恢復:
mv file.txt.bak file.txt
這樣,file.txt 就會恢復成修改前的版本!
4. 刪除某一行
語法:
sed 'Nd' 文件名
- N 代表 行號
- d 代表 刪除
?? 示例:刪除第 2 行
假設 file.txt 內容:
Peter
Alice
Bob
Charlie
Bob
David
執行:
sed '2d' file.txt
輸出:
Peter
Bob
Charlie
Bob
David
?? 刪除最后一行
sed '$d' file.txt
輸出:
Peter
Bob
Charlie
Bob
$ : 代表最后一行
?? 刪除所有包含 Bob 的行
sed '/Bob/d' file.txt
? 輸出
Peter
Charlie
/內容/d 就是按內容刪除,N d 就是按行號刪除!
?? 刪除所有空行
sed '/^$/d' file.txt
^$ 代表空行,所以這條命令能刪掉所有空白行!
?? 刪除前 N 行
語法:
sed '1,5d' file.txt
- 1,5d:刪除從第 1 行到第 5 行
- 最終效果:刪除前 5 行,只保留第 6 行之后的內容
適用于清理文件頭部信息,刪除表頭或無用數據。
?? 刪除第 N 行到最后一行
語法:
sed '2,$d' file.txt
- 2,$ :表示從第 2 行到最后一行
- d:表示刪除
最終效果:只保留第一行,刪除后面所有內容
?? 刪除包含多個關鍵詞的行
語法:
sed '/error\|fail/d' file.txt
- /error\|fail/ : 匹配 error 或 fail
- d :刪除匹配的行
最終效果:刪除所有包含 "error" 或 "fail" 的行
示例
假設 file.txt 里有:
process completed successfully.
error: Cannot find file.
warning: Low memory.
fail: Connection lost.
system running normally.
執行:
sed '/error\|fail/d' file.txt
輸出:
process completed successfully.
warning: Low memory.
system running normally.
適用于日志分析、錯誤排查,快速過濾無用日志。
?? 刪除所有以字母開頭的行
語法
sed '/^[a-zA-Z]/d' file.txt
- ^ :匹配行首
- [a-zA-Z] : 匹配任何字母
- d : 刪除匹配的行
最終效果:刪除所有以字母開頭的行
?? 示例
假設 file.txt 里有:
yaml
Alice
12345
Bob
7890
Charlie
執行:
sed '/^[a-zA-Z]/d' file.txt
輸出::
12345
7890
適用于日志清理、去除無用數據、提取數值信息。
5. 只顯示某些行
語法:
sed -n 'Np' 文件名
- N 代表 行號
- p 代表 打印
?? 示例:打印第 2 行
假設 file.txt 內容:
Peter
Alice
Bob
Charlie
Bob
David
執行:
sed -n '2p' file.txt
輸出:
Alice
只顯示匹配內容,不輸出其他內容,可以加 -n。
?? 顯示 2-4 行
sed -n '2,4p' file.txt
輸出:
Alice
Bob
Charlie
適用于日志分析、查看部分數據!
?? 只顯示匹配的行
如果你想找出所有包含 Bob 的行:
sed -n '/Bob/p' file.txt
-n 選項的作用是 關閉默認輸出,只顯示 p(print)匹配的內容。
6. 在指定行前/后插入文本
假設 file.txt 內容:
Peter
Alice
Bob
Charlie
?? 在第 2 行前插入 "Henry is comming"
sed '2i\ Henry is comming' file.txt
輸出:
Peter
Henry is coming
Alice
Bob
Charlie
"Henry is coming" 被插入到 第 2 行前面,所以 Alice 變成了第 3 行。
?? 在第 3 行后插入 "David is comming"
sed '3a\ David is comming' file.txt
輸出:
Peter
Henry is coming
Alice
David is comming
Bob
Charlie
i 代表 insert,在某行前插入內容;a 代表 append,在某行后追加內容。
三、sed 其他常見操作
?? 修改某一行
語法:
sed '3c\ This is a new line' file.txt
- 3c\ :表示修改第 3 行
- "This is a new line" : 替換的新內容
最終效果:第 3 行的內容會被 "This is a new line" 替換
示例:
假設 file.txt 里有:
Alice
Bob
Charlie
David
Eve
執行:
sed '3c\ This is a new line' file.txt
輸出:
Alice
Bob
This is a new line
David
Eve
c\ 命令用于修改某一行的內容,適用于日志清理、格式調整。
?? 提取包含數字的行
語法:
sed -n '/[0-9]/p' file.txt
- -n :只顯示匹配的行
- [0-9] :匹配數字
- p :打印匹配的行
最終效果:只顯示包含數字的行,忽略其他行
?? 示例
假設 file.txt 里有:
Alice
Bob
12345
Charlie
7890
David
執行:
sed -n '/[0-9]/p' file.txt
輸出:
12345
7890
適用于日志分析、數據提取、過濾出數值行。
?? 刪除空格(去除所有行首和行尾空格)
語法:
sed 's/^[ \t]*//;s/[ \t]*$//' file.txt
- ^[ \t]*// : 刪除行首的空格和 Tab
- [ \t]*$// : 刪除行尾的空格和 Tab
最終效果:去除行首和行尾的空格
?? 示例
假設 file.txt 里有:
Alice
Bob
Charlie
David
執行:
sed 's/^[ \t]*//;s/[ \t]*$//' file.txt
輸出:
nginx
Alice
Bob
Charlie
David
適用于格式化文本、清理無用空格,讓文件更整潔!
?? 刪除 HTML 標簽
語法:
sed 's/<[^>]*>//g' file.html
- <[^>]*> : 匹配 HTML 標簽
- s/...//g : 替換為空
最終效果:去掉 HTML 標簽,只保留純文本
?? 示例
假設 file.html 里有:
<h1>Hello</h1>
<p>Welcome to <b>Linux</b> commands!</p>
執行:
sed 's/<[^>]*>//g' file.html
輸出:
Hello
Welcome to Linux commands!
適用于網頁數據提取、去除 HTML 代碼,保留文本內容。
?? 刪除注釋(# 或 // 開頭的行)
語法:
sed '/^#/d' config.txt # 刪除 # 開頭的注釋
sed '/^\/\//d' code.cpp # 刪除 // 開頭的注釋
- ^# : 匹配 # 開頭的行
- ^// : 匹配 // 開頭的行
- d : 刪除匹配的行
最終效果:刪除配置文件或代碼中的注釋
?? 示例
假設 config.txt 里有:
# This is a comment
server_port=8080
# Another comment
server_name=localhost
執行:
sed '/^#/d' config.txt
輸出:
server_port=8080
server_name=localhost
適用于去除無用注釋,讓配置文件更加簡潔清晰!
??sed -e 命令的使用
-e 選項的作用是在同一條 sed 命令中執行多個操作,可以替換、刪除、插入等多種操作同時進行。
sed -e 基礎用法:
sed -e '操作1' -e '操作2' 文件
作用:按順序執行多個 sed 操作。
1. 依次執行多個替換
示例:
sed -e 's/Alice/Jane/' -e 's/Bob/John/' file.txt
作用:
- 替換 "Alice" 為 "Jane"
- 替換 "Bob" 為 "John"
?? 示例
文件 file.txt
Alice is a student.
Bob is a teacher.
執行命令:
sed -e 's/Alice/Jane/' -e 's/Bob/John/' file.txt
輸出:
Jane is a student.
John is a teacher.
多個 -e 選項可以讓 sed 依次執行多個替換操作!
2. 依次執行“刪除 + 替換”
示例:
sed -e '/^#/d' -e 's/error/ERROR/g' file.txt
作用:
- 刪除 # 開頭的注釋行
- 將 error 替換成 ERROR
?? 示例
文件 file.txt:
# This is a comment
Server is running
error: file not found
# Another comment
執行命令:
sed -e '/^#/d' -e 's/error/ERROR/g' file.txt
輸出:
Server is running
ERROR: file not found
適用于日志清理,先刪除注釋,再格式化錯誤信息!
3. 結合 -e 實現多行插入
示例:
sed -e '2i\ --- Start ---' -e '4a\ --- End ---' file.txt
作用:
- 在第 2 行前插入 --- Start ---
- 在第 4 行后插入 --- End ---
?? 示例
文件 file.txt:
Line1
Line2
Line3
Line4
Line5
執行命令:
sed -e '2i\ --- Start ---' -e '4a\ --- End ---' file.txt
輸出:
Line1
--- Start ---
Line2
Line3
Line4
--- End ---
Line5
適用于文本標記、自動化修改文件!
4. -e 結合 -i 直接修改文件
示例:
sed -i -e 's/foo/bar/g' -e 's/old/new/g' file.txt
作用:
- 將 foo 替換為 bar
- 將 old 替換為 new
- 直接修改 file.txt,而不是只輸出到終端!
-i 讓 sed 直接修改文件內容,而不是只顯示修改后的文本!
5. -e 結合 -n 只顯示匹配的結果
示例:
sed -n -e '/error/p' -e '/fail/p' file.txt
作用:
- 僅打印包含 "error" 或 "fail" 的行
- 忽略其他行的輸出(-n)
適用于日志分析,快速提取重要信息!
四、sed 結合 find、grep、awk 等常見組合命令
在實際工作中,sed 通常不會單獨使用,而是和 find、grep、awk、xargs、tee 等命令組合,形成更強大的文本處理工具鏈,適用于 批量修改文件、日志分析、數據處理 等場景。??
1. sed + find:批量修改多個文件
場景:批量替換某個目錄下所有 .txt 文件中的 hello為 hi
find /path -type f -name "*.txt" -exec sed -i 's/hello/hi/g' {} +
作用:
- find /path -type f -name "*.txt" : 查找 /path 目錄下所有 .txt 文件
- -exec sed -i 's/hello/hi/g' {} + : 在所有找到的文件里替換 hello 為 hi
- + : 批量執行,提高效率(比 \; 更快)
示例 : 假設 /path 目錄下有:
file1.txt (包含 "hello world")
file2.txt (包含 "hello Alice")
執行后:
file1.txt -> "hi world"
file2.txt -> "hi Alice"
適用場景:
- 批量修改配置文件
- 處理大量日志文件
- 自動化代碼修改
2. sed + grep:只修改包含特定內容的行
場景:只修改包含 "error" 的行,把 "failed" 替換為 "FAILED"
grep "error" file.txt | sed 's/failed/FAILED/g'
作用:
- grep "error" file.txt : 先篩選 出包含 "error" 的行
- sed 's/failed/FAILED/g' : 只修改這些行 中的 "failed"
示例 : 原 file.txt
Task 1: success
Task 2: error, operation failed
Task 3: success
Task 4: error, connection failed
執行:
grep "error" file.txt | sed 's/failed/FAILED/g'
輸出:
Task 2: error, operation FAILED
Task 4: error, connection FAILED
適用場景:
- 過濾日志文件,并修改某些內容
- 只修改特定關鍵字所在的行
- 避免誤修改不相關的行
3. sed + awk:精準修改特定列
場景:批量修改 CSV 文件的第 2 列,把 low 改成 LOW
awk -F, '{ $2=gensub(/low/, "LOW", "g", $2); print }' OFS=, file.csv
作用:
- -F, : 以逗號分隔
- gensub(/low/, "LOW", "g", $2) : 只替換第 2 列的 low
- OFS=, : 保持逗號分隔格式
- 最終:只修改第 2 列,保留其他列不變
示例 :原 file.csv
ID,Status,Score
1,low,50
2,medium,70
3,low,40
4,high,90
執行:
awk -F, '{ $2=gensub(/low/, "LOW", "g", $2); print }' OFS=, file.csv
輸出:
ID,Status,Score
1,LOW,50
2,medium,70
3,LOW,40
4,high,90
適用場景:
- 精確修改某一列的內容,不影響其他列
- 適用于 CSV、TSV、日志文件
- 比 sed 更精準,sed 只能針對整行替換,而 awk 能操作特定字段
4. sed + xargs:批量修改多個文件
場景:在多個 .log 文件里批量替換 "DEBUG" 為 "INFO"
find /var/log -type f -name "*.log" | xargs sed -i 's/DEBUG/INFO/g'
作用:
- find /var/log -type f -name "*.log" : 查找所有 .log 文件
- xargs sed -i 's/DEBUG/INFO/g' : 批量替換,不會逐個執行(比 -exec 更快)
適用場景:
- 高效處理海量文件(比 find -exec 更快)
- 避免 Too many arguments 錯誤(當文件太多時,xargs 會批量處理)
5. sed + tee:邊修改邊輸出
場景:把 config.conf 里的 "8080" 端口改成 "9090",同時保存到 new_config.conf
sed 's/8080/9090/g' config.conf | tee new_config.conf
作用:
- sed 's/8080/9090/g' config.conf : 修改端口
- tee new_config.conf : 同時輸出到終端和 new_config.conf
適用場景:
- 保留原始文件,不直接修改
- 先檢查輸出,確保無誤再用 -i 修改
6. sed + diff:對比修改前后的差異
場景:我們有一個 file.txt,其中包含 "error",想用 sed 把它改成 "ERROR",但在真正修改前,先用 diff 對比 修改前后的差異,確保不會誤改。
示例
file.txt 內容:
Task 1: success
Task 2: error, operation failed
Task 3: success
Task 4: error, connection lost
(1) 用 sed 預覽修改
sed 's/error/ERROR/g' file.txt
預期輸出:
Task 1: success
Task 2: ERROR, operation failed
Task 3: success
Task 4: ERROR, connection lost
(2) 用 diff 對比修改前后
diff <(cat file.txt) <(sed 's/error/ERROR/g' file.txt)
輸出:
2c2
< Task 2: error, operation failed
---
> Task 2: ERROR, operation failed
4c4
< Task 4: error, connection lost
---
> Task 4: ERROR, connection lost
解釋:
- 2c2 : 第 2 行變化:
< Task 2: error, operation failed # 舊內容
---
> Task 2: ERROR, operation failed # 新內容
- 4c4 : 第 4 行也有類似的變化。
(3) 確認無誤后,正式修改文件
sed -i 's/error/ERROR/g' file.txt
-i 直接修改 file.txt,不用手動保存
適用場景:
- 檢查 sed 修改的影響,避免誤改
- 對比文件修改前后的版本,避免數據丟失
- 適用于日志分析、代碼改動、批量文本處理
sed + diff 讓你在修改前先檢查變化,確保修改準確無誤,數據安全性更高!
五、總結:掌握 sed,讓文本處理更高效!
sed 是 Linux 中強大的文本處理工具,它不僅能 查找、替換、刪除、插入文本,還能結合 find、grep、awk、xargs 等命令,實現批量修改和自動化處理。無論是 日志分析、批量修改配置文件、處理文本數據,sed 都能幫你 減少重復勞動,大幅提升工作效率。
學完這篇文章,你應該掌握了這些核心操作:
基礎操作:
- 通過 s/old/new/g 實現 文本替換(相當于 Ctrl+H)。
- 用 -i 選項 直接修改文件,無需手動打開編輯。
- 刪除某行(按行號刪除、按匹配模式刪除)。
- 顯示或提取特定內容(比如第 10 行、包含某個關鍵字的行)。
- 在指定行前/后插入文本,適用于配置文件修改。
進階技巧:
- 結合 find,批量修改多個文件,不再逐個手動編輯。
- 結合 grep,只修改包含特定內容的行,提高精準度。
- 結合 awk,針對特定列進行修改,處理 CSV、日志等結構化數據。
- 結合 xargs,高效處理多個文件,節省時間。
- 結合 tee,邊修改邊輸出,適用于調試和日志處理。
適用場景:
- 批量修改代碼或配置文件,比如 替換端口號、修改日志級別、更新 URL 等。
- 清理和格式化日志,如 刪除多余信息、提取 IP 地址、去除 HTML 標簽或注釋。
- 數據分析和處理,用于 提取特定字段、格式化文本數據,與 awk 結合使用更加強大。
學會 sed,你就能輕松修改文件,不再手動改一堆文本!
進一步學習:學完 sed,下一步該學什么?
恭喜你!現在你已經掌握了 sed 的核心用法,并且知道如何 高效查找、替換、刪除、插入文本,大幅提高了處理文本的效率。但在 Linux 文本處理的世界里,sed 只是 第一塊拼圖,還有一個更加強大的工具——awk!
sed 主要用于修改和處理文本,而 awk 更適合分析和提取數據,比如:
- 提取 CSV 文件中的某一列數據。
- 計算日志中某個關鍵詞出現的次數。
- 統計服務器訪問日志中,每個 IP 的請求次數。
- 對文本數據進行篩選、計算、分組統計等操作。
如果 sed 是“文本編輯器”,那 awk 就是“文本計算器”!