文章目錄
- 前言
- 一、什么是sed
- 二、sed的原理
- 2.1 sed工作流程的三個步驟
- 2.2 sed的兩個重要空間:
- 2.3 sed的具體運作流程
- 三、sed的常見用法
- 3.1 sed的基本格式
- 3.2 常用選項
- 3.3 常用操作
- 3.3.1 基本語法規則
- 3.3.2 常用操作命令
- 3.4 操作用法示例
- 3.4.1 輸出符合條件的文本(`p` 正常輸出)
- 3.4.2 結合正則表達式進行輸出
- 3.4.3 刪除符合條件的文本`d`
- 3.4.4 替換符合條件的文本`tr`
- 3.4.5 遷移符合條件的文本
- 3.4.6 使用腳本編輯文件
- 四、生產環境的sed使用
- 4.1 修改ip/監聽地址
- 4.2 編寫vsftpd服務的自動配置
- 總結
前言
想象一下,你正在整理一堆雜亂的文件,手忙腳亂地復制、粘貼、刪除某些內容,甚至還要批量替換某些詞。如果手動操作,不僅容易出錯,還特別浪費時間。這時候,sed就像一位低調但高效的文本編輯助手,幫你自動完成這些繁瑣的任務。
它不會像圖形化工具那樣花哨,但只要你告訴它規則,比如“把所有的‘蘋果’換成‘橙子’”或者“刪除空行”,它就能眨眼間搞定。它的風格簡潔直接,擅長處理一行一行的文本,就像流水線上的工人,精準又高效。
不過,如果你覺得sed只能做簡單的“查找替換”,那就太小看它了——它還能匹配模式、條件編輯,甚至結合正則表達式玩出更復雜的操作。而當你熟悉了sed之后,可能會發現,有時候你需要的不只是編輯文本,還要分析、計算、提取數據……這時候,另一位更強大的搭檔awk就該登場了。
但別急,先讓我們把sed的基本功練扎實,畢竟再厲害的編程技巧,也得從最順手的小工具開始。
一、什么是sed
sed(Stream EDitor,流編輯器)是一個強大而輕量的流式文本編輯器。它誕生于 Unix 早期,由 Lee E. McMahon 于 1973 年到 1974 年間開發,是 Linux/Unix 系統中最基礎和最重要的工具之一。
它的核心特點如下:
- 非交互式:與
vim
或nano
這類交互式編輯器不同,sed
通過接收命令或腳本文件來批量處理文本,無需用戶介入。這使得它非常適合在腳本和自動化任務中使用。 - 面向數據流:
sed
逐行處理輸入(可以是文件或標準輸入),將結果輸出到標準輸出。它不會直接修改原始文件(除非明確指定),這保證了操作的安全性。 - 功能強大:主要功能包括文本替換、刪除、打印、插入、追加、模式匹配等,尤其擅長查找和替換。
- 基于正則表達式:其強大的模式匹配能力建立在正則表達式之上,可以非常靈活地定位文本。
簡單來說,sed
就像一個預設了規則的過濾器和加工器,文本流經過它,會被自動地按照指令進行修改和整理。
二、sed的原理
2.1 sed工作流程的三個步驟
理解 sed
的原理是掌握它的關鍵。其工作流程可以概括為以下三個步驟:
-
讀取(Read):
sed
從輸入流(文件或管道)中一次讀取一行內容。- 將這行內容存儲在其內部的臨時緩沖區中,這個緩沖區稱為模式空間(Pattern Space)。
-
執行(Execute):
- 將用戶提供的所有
sed
命令(或腳本中的命令)按順序應用到模式空間中的內容上。 - 這是核心步驟,所有的替換、刪除、打印等操作都在這里發生。
- 將用戶提供的所有
-
輸出(Print):
- 執行完所有命令后,除非有特殊指令(如
d
刪除命令),否則模式空間中當前的內容會被自動輸出到標準輸出(屏幕)。 - 然后清空模式空間,接著讀取下一行,重復上述過程,直到處理完所有輸入行。
- 執行完所有命令后,除非有特殊指令(如
這種 “讀取-執行-輸出” 的流水線模式,使得
sed
在處理超大文件時效率極高,因為它永遠不會將整個文件加載到內存中。
2.2 sed的兩個重要空間:
- 模式空間(Pattern Space):如上所述,這是當前處理行的“工作臺”,大部分操作都在這里進行。
- 保持空間(Hold Space):一個輔助的緩沖區,用作臨時存儲。模式空間的內容可以和保持空間進行交換(
g
、h
)、追加(G
)等操作,用于實現更復雜的多行處理功能。
2.3 sed的具體運作流程
- 將一行的內容讀入模式空間。
- 從指定的操作指令中取出第一條指令,判斷是否匹配pattern。
- 如果不匹配,直接不執行匹配條件后的編輯命令,轉而讀取下一條指令;如果匹配則執行編輯命令,對模式空間內的內容進行編輯,然后讀取下一條指令。
- 當所有指令執行完畢,默認會輸出模式空間內的內容,然后清空模式空間,讀取下一行的內容。
- 當完成對所有行的讀取時,結束。
注意:默認情況下所有的 sed 命令都是在模式空間內執行的,因此輸入的文件并不會發生任何變化,除非是用重定向存儲輸出(
-i
)。
三、sed的常見用法
3.1 sed的基本格式
調用sed命令有兩種基本格式:
# 一、直接輸入操作
sed [選項] '操作' 參數
# 二、通過調用腳本進行操作
sed [選項] -f scriptfile 參數
其中,“參數”指操作的目標文件,多個文件時用逗號分隔;“scriptfile”為腳本文件,需用 -f
指定。
3.2 常用選項
以下是 sed
常用選項的表格整理:
短選項 | 長選項 | 功能描述 |
---|---|---|
-e | --expression= | 用指定命令或腳本處理輸入文件,可多次使用以疊加修改 |
-f | --file= | 用指定腳本文件中的命令處理輸入文件 |
-h | --help | 顯示幫助信息并退出 |
-n | --quiet /silent | 僅顯示被腳本處理后的行(默認輸出所有行) |
-i.bak | - | 直接修改原文件(.bak 為備份擴展名,可省略則僅修改不備份) |
-r /-E | - | 使用擴展正則表達式(-r 為GNU擴展,-E 符合POSIX) |
-s | - | 將多個輸入文件視為獨立文件,而非連續流(默認合并處理) |
注:
-i
和-i.bak
實際行為相同,差異在于是否保留備份文件(如-i
直接覆蓋,-i.bak
保留原文件備份)。- 部分選項(如
-r
/-E
)在不同系統實現中可能存在別名差異。
3.3 常用操作
3.3.1 基本語法規則
[n1[,n2]]
格式用于指定行范圍,其中 n1
和 n2
均為行號。
- 單行操作:
n1
表示僅對第n1
行生效。 - 范圍操作:
n1,n2
表示對第n1
行至第n2
行生效。 - 省略
n1
:如,n2
表示從第1行至第n2
行。 - 省略
n2
:如n1,
表示從第n1
行至文件末尾。
3.3.2 常用操作命令
-
a
:追加內容
在指定行下方追加新行。
示例:5a
在第5行下方追加,輸入內容后以.
結束。 -
c
:替換行
將選定行替換為新內容。
示例:5,10c
替換第5-10行,輸入新內容后以.
結束。 -
d
:刪除行
刪除選定行。
示例:5,20d
刪除第5-20行。 -
i
:插入行
在選定行上方插入新內容。
示例:5i
在第5行上方插入,輸入內容后以.
結束。 -
p
:打印內容
顯示選定行內容,常與-n
參數聯用顯示行號。
示例:5,20p
打印第5-20行。 -
s
:替換文本
對選定行執行文本替換,語法為s/原內容/新內容/[g]
。g
為全局替換標志(可選)。
示例:5,10s/foo/bar/g
將第5-10行的foo
替換為bar
。
-
y
:字符轉換
按字符一一映射轉換,語法為y/原字符集/新字符集/
。
示例:5,20y/abc/ABC/
將第5-20行的a→A
、b→B
、c→C
。
3.4 操作用法示例
3.4.1 輸出符合條件的文本(p
正常輸出)
sed -n 'p' test.txt # 輸出所有內容,等同于 cat
sed -n '3p' test.txt # 輸出第3行
sed -n '3,5p' test.txt # 輸出3~5行
sed -n 'p;n' test.txt # 輸出所有奇數行
sed -n 'n;p' test.txt # 輸出所有偶數行
sed -n '1,5{p;n}' test.txt # 輸出1~5行之間的奇數行
sed -n '10,${n;p}' test.txt # 輸出第10行至文件尾的偶數行
sed -n 'h;n;p;g;p' test.txt #輸出所有內容,但兩行間的內容互換,h,復制到保存空間,g,從保存空間獲取到模式空間
3.4.2 結合正則表達式進行輸出
sed -n '/the/p' test.txt # 輸出包含 the 的行
sed -n '4,/the/p' test.txt # 輸出從第4行至第一個包含 the 的行
sed -n '/the/=' test.txt # 輸出包含 the 的行號
sed -n '/^PI/p' test.txt # 輸出以 PI 開頭的行
sed -n '/[0-9]$/p' test.txt # 輸出以數字結尾的行
sed -n '/\<woood\>/p' test.txt # 輸出包含單詞 wood 的行,'\< \>'是邊界,被包含的內容會被精確匹配
3.4.3 刪除符合條件的文本d
nl test.txt | sed '3d' # 刪除第3行
nl test.txt | sed '3,5d' # 刪除3~5行
nl test.txt | sed '/cross/d' # 刪除包含 cross 的行
sed '/^[a-z]/d' test.txt # 刪除以小寫字母開頭的行
sed '/\.$/d' test.txt # 刪除以“.”結尾的行
sed '/^$/d' test.txt # 刪除所有空行# 刪除連續空行(只保留一個)可使用:cat -s test.txt
3.4.4 替換符合條件的文本tr
sed 's/the/THE/' test.txt # 每行第一個 the 替換為 THE
sed 's/l/L/2' test.txt # 每行第二個 l 替換為 L
sed 's/the/THE/g' test.txt # 所有 the 替換為 THE
sed 's/o//g' test.txt # 刪除所有字母 o
sed 's/^/#/' test.txt # 每行行首插入 #
sed '/the/s/^/#/' test.txt # 在包含 the 的行首插入 #
sed 's/$/EOF/' test.txt # 每行行尾插入 EOF
sed '3,5s/the/THE/g' test.txt # 將第3~5行中所有 the 替換為 THE
sed '/the/s/o/O/g' test.txt # 在包含 the 的行中所有 o 替換為 O
# 直接修改配置文件示例:
sed -i.bak 's/SELINUX=disabled/SELINUX=enable/' /etc/selinux/config
3.4.5 遷移符合條件的文本
-
H:復制到剪貼板;
-
g、G:將剪貼板中的數據覆蓋/追加至指定行;
-
w:保存為文件;
-
r:讀取指定文件;
-
a:追加指定內容。具體操作方法如下所示。
-
I,i 忽略大小寫
sed '/the/{H;d};$G' test.txt # 將包含 the 的行移至文件末尾
sed '1,5{H;d};17G' test.txt # 將第1~5行內容轉移至第17行后
sed '/the/w out.file' test.txt # 將包含 the 的行另存為文件
sed '/the/r /etc/hostname' test.txt # 在包含 the 的每行后添加文件內容
sed '3aNew' test.txt # 在第3行后插入新行,內容為 New
sed '/the/aNew' test.txt # 在包含 the 的每行后插入新行
sed '3aNew1\nNew2' test.txt # 在第3行后插入多行內容
sed '/the/IaNew' test.txt # I,i 可用于忽略大小寫
3.4.6 使用腳本編輯文件
sed '1,5{H;d};16G'
以上命令可以轉換成腳本文件,將多個編輯指令存入腳本文件(每行一條),通過 -f
調用:
# 編輯腳本文件:
vi opt.list
內容如下:
1,5H
1,5d
16G# 使用腳本:
sed -f opt.list test.txt
||
表示上一條命令執行失敗后才執行下一條。
四、生產環境的sed使用
4.1 修改ip/監聽地址
需求: 需要將ens33網絡接口的IP地址修改為 192.168.10.100
sed -i 's/^IPADDR=.*/IPADDR=192.168.10.100/' /etc/sysconfig/network_scripts/ifcfg-ens33
需求: 需要將 Apache 的監聽地址修改為 192.168.10.100,端口修改為 8080
# 修改監聽地址
sudo sed -i 's/^Listen .*/Listen 192.168.10.100:8080/'
/etc/httpd/conf/httpd.conf# 修改 ServerName
sed -i 's/^ServerName .*/ServerName 192.168.10.100:8080/'
/etc/httpd/conf/httpd.conf
4.2 編寫vsftpd服務的自動配置
需求: 編寫一個腳本,用來調整 vsftpd 服務配置,要求禁止匿名用戶,但允許本地用戶(也允許寫入)。
#!/bin/bash
SAMPLE="/usr/share/doc/vsftpd-3.0.2/EXAMPLE/INTERNET_SITE/vsftpd.conf"
#系統自帶的變量路徑
CONFIG="/etc/vsftpd/vsftpd.conf"# 備份原配置文件
[ ! -e "$CONFIG.bak" ] && cp $CONFIG $CONFIG.bak# 調整配置
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
grep "listen" $CONFIG || sed -i '$alisten=YES' $CONFIG# 重啟并設置開機自啟
systemctl restart vsftpd
systemctl enable vsftpd
總結
別停下,你已手握文本處理的利刃!
sed 看似簡單,卻是自動化腳本的靈魂。每一次精準的替換、每一次高效的刪除,都在為你節省寶貴的時間。
記住:高手不是一天練成的,而是在一次次“查找-替換”中磨出來的。
你已經掌握了原理,接下來就是大膽實踐:
- 去清理日志、去修改配置、去批量重命名……
- 讓 sed 成為你的得力助手,把重復勞動交給機器!
未來的你,會感謝現在努力學習的自己。繼續征服命令行,下一站:awk! 🚀