從入門到實戰:Linux sed命令全攻略,文本處理效率翻倍
文章目錄
- 從入門到實戰:Linux sed命令全攻略,文本處理效率翻倍
- 一、認識sed:什么是流編輯器?
- 二、吃透sed工作原理:為什么它能高效處理文本?
- 三、sed基礎用法:命令格式與核心選項
- 3.1 核心選項解析
- 3.2 核心操作指令
- 四、sed實戰演練:從基礎到進階案例
- 4.1 文本查看:精準輸出指定內容(p指令)
- 4.2 文本刪除:批量清理無用內容(d指令)
- 4.3 文本替換:批量修改內容(s/c/y指令)
- 4.3.1 s指令:字符串替換(最常用)
- 4.3.2 c指令:整行替換
- 4.3.3 y指令:字符轉換(按位置一一對應)
- 4.4 文本遷移:插入、追加與保存(a/i/w/r指令)
- 4.4.1 插入/追加(i/a指令)
- 4.4.2 保存/讀取(w/r指令)
- 4.5 多行處理:保留空間的應用(H/G指令)
- 4.6 腳本批量處理:多指令集成(-f選項)
- 五、生產環境實戰:sed的高頻應用場景
- 5.1 修改網絡配置:設置IP地址
- 5.2 調整Apache配置:修改監聽地址與端口
- 5.3 配置vsftpd服務:禁止匿名登錄
- 5.4 提取網卡IP地址:結合管道與正則
- 六、sed使用注意事項
- 總結
在Linux系統中,文本處理是日常工作中繞不開的環節。無論是分析日志、修改配置文件,還是批量處理數據,都需要高效的文本編輯工具。sed命令作為一款流編輯器,憑借其強大的批量處理能力和靈活的腳本支持,成為了Linux運維、開發人員的必備工具。本文將從sed的基本概念出發,循序漸進講解其原理、用法,并通過實戰案例展示其在生產環境中的應用,助你輕松掌握這一高效文本處理利器。
一、認識sed:什么是流編輯器?
sed全稱為“Stream Editor”(流編輯器),它與傳統的交互式編輯器(如vi)不同,不直接打開文件進行交互式編輯,而是通過腳本指令對輸入的文本流(文件、管道、標準輸入等)進行逐行處理。
其核心價值在于:
- 自動化處理:可通過腳本實現重復、繁瑣的文本編輯操作自動化,避免人工逐行修改的低效與失誤。
- 批量處理:支持同時處理單個或多個文件,輕松實現大規模文本的統一修改。
- 管道集成:可與Linux其他命令(如grep、cat、ifconfig等)通過管道結合,構建強大的文本處理流水線。
二、吃透sed工作原理:為什么它能高效處理文本?
想要靈活運用sed,必須先理解其底層工作流程。sed的核心是“模式空間”(Pattern Space)——一個臨時緩沖區,所有編輯操作都在其中進行,默認不會修改原文件(除非主動指定)。其完整工作流程可分為讀取、執行、顯示三個循環步驟:
- 讀取(Read):從輸入流中讀取一行文本,存儲到模式空間中,清空模式空間原有內容。
- 執行(Execute):按照指定的腳本指令,對模式空間中的文本進行匹配和編輯。若未指定行地址,指令將作用于所有行;若指定了行地址,僅匹配的行會被處理。
- 顯示(Print):將模式空間中處理后的文本輸出到輸出流(默認是屏幕),隨后清空模式空間。
重復以上三步,直到輸入流中的所有行都處理完畢。
關鍵注意點:默認情況下,sed僅修改模式空間中的內容,原文件保持不變。若需修改原文件,需使用-i
選項(建議先備份,如-i.bak
會保留原文件為.bak
備份)。
三、sed基礎用法:命令格式與核心選項
sed的命令格式主要有兩種,分別適用于簡單指令和復雜腳本場景:
# 1. 直接指定指令處理文本
sed [選項] '操作' 文件名/輸入流
# 2. 通過腳本文件處理文本(適用于多指令場景)
sed [選項] -f 腳本文件 文件名/輸入流
3.1 核心選項解析
sed的選項用于控制處理方式,常用選項如下表所示:
選項 | 英文全稱 | 功能說明 |
---|---|---|
-e | –expression | 允許在同一命令中指定多個編輯指令(多指令處理) |
-n | –quiet/silent | 取消默認輸出(僅輸出經過編輯指令處理后的內容) |
-f | –file | 從指定的腳本文件中讀取編輯指令 |
-i | –in-place | 直接修改原文件(危險!建議搭配備份,如-i.bak ) |
-r/-E | –regexp-extended | 使用擴展正則表達式(無需對`()、{}、 |
-s | –separate | 將多個文件視為獨立文件處理,而非連續的文本流 |
-h | –help | 顯示幫助信息 |
3.2 核心操作指令
sed的“操作”由“行地址”和“動作指令”組成,格式為[n1[,n2]]動作
,其中n1,n2
指定作用的行范圍(可選),動作指定具體編輯操作。常用動作指令如下:
動作 | 功能說明 |
---|---|
p | 打印模式空間中的內容,常與-n 搭配(避免重復輸出) |
d | 刪除模式空間中的匹配行 |
s | 字符串替換,格式為s/被替換內容/替換內容/[選項] (選項:g-全局替換;n-第n次匹配替換) |
a | 在匹配行下方插入指定內容 |
i | 在匹配行上方插入指定內容 |
c | 用指定內容替換匹配的整行 |
y | 字符轉換,格式為y/原字符集/目標字符集/ (按位置一一對應轉換) |
H | 將匹配行復制到“保留空間”(臨時緩存,用于多行處理) |
G | 將保留空間的內容追加到模式空間 |
w | 將匹配行寫入指定文件 |
r | 讀取指定文件的內容,追加到匹配行之后 |
四、sed實戰演練:從基礎到進階案例
以下案例均以demo
文件為測試對象(內容如下),帶你逐步掌握sed的核心用法:
1. Hello, the world!
2. This is a test file.
3. He was short and fat.
4. A wood cross!
5. PI=3.141592653589793238462643383249901429
6. Misfortunes never come alone/single.
7.
8. linux is great!
4.1 文本查看:精準輸出指定內容(p指令)
p
指令用于打印文本,需配合-n
選項(否則會重復輸出默認內容),常用于篩選特定行或匹配內容。
案例 | 命令 | 說明 |
---|---|---|
輸出所有行 | sed -n 'p' demo | 等同于cat demo |
輸出第3行 | sed -n '3p' demo | 僅打印第3行 |
輸出3-5行 | sed -n '3,5p' demo | 打印連續行(3到5行) |
輸出奇數行 | sed -n 'p;n' demo | n 表示“讀取下一行”,先打印當前行再讀下一行,實現奇數行輸出 |
輸出偶數行 | sed -n 'n;p' demo | 先讀下一行,再打印,實現偶數行輸出 |
輸出含“the”的行 | sed -n '/the/p' demo | 按內容匹配(正則),打印含“the”的行 |
輸出以“PI”開頭的行 | sed -n '/^PI/p' demo | 正則匹配行首,^ 表示行首 |
輸出以數字結尾的行 | sed -n '/[0-9]$/p' demo | 正則匹配行尾,$ 表示行尾 |
輸出含“wood”單詞的行 | sed -n '/\<wood\>/p' demo | \<\> 表示單詞邊界,避免匹配“woood”等 |
4.2 文本刪除:批量清理無用內容(d指令)
d
指令用于刪除匹配的行,注意:默認不修改原文件,僅輸出刪除后的結果;若需修改原文件,加-i
選項。
案例 | 命令 | 說明 |
---|---|---|
刪除第3行 | sed '3d' demo | 輸出刪除第3行后的所有內容 |
刪除3-5行 | sed '3,5d' demo | 刪除連續行 |
刪除含“cross”的行 | sed '/cross/d' demo | 刪除匹配內容的行 |
刪除以小寫字母開頭的行 | sed '/^[a-z]/d' demo | 正則匹配行首小寫字母 |
刪除以“.”結尾的行 | sed '/\.$/d' demo | . 是特殊字符,需轉義\ |
刪除空行 | sed '/^$/d' demo | ^$ 匹配空行 |
4.3 文本替換:批量修改內容(s/c/y指令)
替換是sed最常用的功能,核心是s
指令(字符串替換),c
(整行替換)和y
(字符轉換)為輔助。
4.3.1 s指令:字符串替換(最常用)
格式:s/被替換內容/替換內容/[選項]
,選項包括g
(全局替換)、n
(第n次匹配替換)。
- 替換每行第一個“the”為“THE”:
sed 's/the/THE/' demo
- 替換每行第二個“l”為“L”:
sed 's/l/L/2' demo
- 全局替換所有“the”為“THE”:
sed 's/the/THE/g' demo
- 刪除所有“o”(替換為空):
sed 's/o//g' demo
- 3-5行全局替換“the”為“THE”:
sed '3,5s/the/THE/g' demo
- 給含“the”的行首加
#
(注釋):sed '/the/s/^/#/' demo
- 給每行行尾加“EOF”:
sed 's/$/EOF/' demo
4.3.2 c指令:整行替換
- 將第3行替換為“Third line is replaced!”:
sed '3c Third line is replaced!' demo
- 將含“PI”的行替換為“圓周率:3.1415”:
sed '/PI/c 圓周率:3.1415' demo
4.3.3 y指令:字符轉換(按位置一一對應)
- 將“abc”轉換為“ABC”:
echo "abc123" | sed 'y/abc/ABC/'
(輸出“ABC123”)
4.4 文本遷移:插入、追加與保存(a/i/w/r指令)
4.4.1 插入/追加(i/a指令)
- 在第3行前插入“Insert before line 3”:
sed '3i Insert before line 3' demo
- 在第3行后插入“Insert after line 3”:
sed '3a Insert after line 3' demo
- 在含“the”的行后插入多行內容:
sed '/the/a New1\nNew2' demo
(\n
表示換行)
4.4.2 保存/讀取(w/r指令)
- 將含“the”的行保存到
out.txt
:sed '/the/w out.txt' demo
- 將
/etc/hostname
內容追加到含“the”的行后:sed '/the/r /etc/hostname' demo
4.5 多行處理:保留空間的應用(H/G指令)
sed的“保留空間”(Hold Space)是另一個臨時緩沖區,用于暫存多行內容,配合H
(復制到保留空間)和G
(追加到模式空間)實現多行遷移。
- 將含“the”的行遷移到文件末尾:
sed '/the/{H;d};$G' demo
({H;d}
表示“復制到保留空間后刪除當前行”,$G
表示“在最后一行后追加保留空間內容”) - 將1-5行遷移到第7行后:
sed '1,5{H;d};7G' demo
4.6 腳本批量處理:多指令集成(-f選項)
當需要執行多個指令時,可將指令寫入腳本文件,通過-f
調用,更易維護。
- 創建腳本文件
opt.sed
:# 指令1:刪除空行 /^$/d # 指令2:全局替換“the”為“THE” s/the/THE/g # 指令3:給第3行前插入注釋 3i # This is line 3
- 執行腳本:
sed -f opt.sed demo
五、生產環境實戰:sed的高頻應用場景
sed在生產環境中常用于配置文件修改、日志分析、批量處理等場景,以下為典型案例。
5.1 修改網絡配置:設置IP地址
需求:將ens33網卡的IP地址修改為192.168.10.100
,配置文件為/etc/sysconfig/network-scripts/ifcfg-ens33
。
# 使用-i.bak備份原文件,避免失誤無法恢復
sed -i.bak 's/^IPADDR=.*/IPADDR=192.168.10.100/' /etc/sysconfig/network-scripts/ifcfg-ens33
- 解析:
^IPADDR=.*
匹配“IPADDR=”開頭的行,.*
表示任意字符,替換為指定IP。
5.2 調整Apache配置:修改監聽地址與端口
需求:將Apache的監聽地址改為192.168.10.100
,端口改為8080
,配置文件為/etc/httpd/conf/httpd.conf
。
# 修改監聽地址和端口
sudo sed -i 's/^Listen .*/Listen 192.168.10.100:8080/' /etc/httpd/conf/httpd.conf
# 修改ServerName
sudo sed -i 's/^ServerName .*/ServerName 192.168.10.100:8080/' /etc/httpd/conf/httpd.conf
5.3 配置vsftpd服務:禁止匿名登錄
需求:編寫腳本,禁止vsftpd匿名登錄,允許本地用戶登錄并寫入。
#!/bin/bash
# 腳本名:config_vsftpd.sh
# 1. 定義路徑
SAMPLE="/usr/share/doc/vsftpd-3.0.2/EXAMPLE/INTERNET_SITE/vsftpd.conf"
CONFIG="/etc/vsftpd/vsftpd.conf"# 2. 備份原配置(若未備份)
[ ! -e "$CONFIG.bak" ] && cp $CONFIG $CONFIG.bak# 3. 基于樣本配置修改:禁止匿名登錄,允許本地用戶及寫入
sed -e '/^anonymous_enable/s/YES/NO/g' $SAMPLE > $CONFIG
sed -i -e '/^local_enable/s/NO/YES/g' -e '/^write_enable/s/NO/YES/g' $CONFIG# 4. 若沒有listen配置,添加到文件末尾
grep "listen" $CONFIG || sed -i '$alisten=YES' $CONFIG# 5. 重啟服務并設置開機自啟
systemctl restart vsftpd
systemctl enable vsftpd
執行腳本:chmod +x config_vsftpd.sh && ./config_vsftpd.sh
5.4 提取網卡IP地址:結合管道與正則
需求:從ifconfig ens33
的輸出中提取IP地址。
ifconfig ens33 | sed -rn '2s/.*inet ([0-9.]+) .*/\1/p'
- 解析:
2s
:作用于第2行(ifconfig輸出中IP通常在第2行);.*inet ([0-9.]+) .*
:正則匹配“inet ”后的IP地址([0-9.]+
匹配IP,()
分組提取);\1
:引用分組1的內容(即IP地址);-r
:使用擴展正則,無需轉義()
;-n
:取消默認輸出,僅打印匹配結果。
六、sed使用注意事項
- 原文件保護:使用
-i
修改原文件前,務必先備份(如-i.bak
),避免誤操作導致數據丟失。 - 正則轉義:默認情況下sed使用基礎正則,
()、{}、|
等特殊字符需轉義(如\(
);若使用-r/-E
選項,可直接使用擴展正則,無需轉義。 - 行地址范圍:
n1,n2
表示“從n1到n2行”,n1~n2
表示“從n1行開始,每隔n2行”(如1~2
表示奇數行)。 - 多指令分組:對同一行執行多個指令時,可使用
{指令1;指令2;...}
分組(如sed '/root/{s/root/ROOT/;s/x/X/g}' /etc/passwd
)。
總結
sed作為Linux下的流編輯器,憑借“逐行處理+腳本驅動”的特性,在文本批量處理場景中效率遠超交互式編輯器。本文從原理到實戰,覆蓋了sed的核心用法與生產場景,掌握這些內容后,你可以輕松應對日志分析、配置修改、數據清洗等常見任務。
sed的功能遠不止于此,結合正則表達式和腳本編程,還能實現更復雜的文本處理邏輯。建議多動手練習,根據實際需求靈活組合指令,逐步提升文本處理效率!