Linux 中的 SED 指令是一個非互動式串流編輯器,它逐行讀取輸入,應用模式和規則進行文字轉換,並將結果寫入標準輸出或檔案。
使用 sed 進行查找和替換、行選擇、刪除、插入以及在腳本、管道和伺服器管理中快速自動化。
如果您是 Linux 系統中 sed 命令的新手,本使用者指南將引導您了解從基本語法到主機託管、DevOps 和系統管理任務中使用的實際單行命令的所有內容。
您將學習 sed 的基本原理、高級技巧和安全的就地編輯,並透過您可以立即運行的簡單範例進行解釋。
Linux 中的 SED 指令是什麼?

sed(流編輯器的縮寫)是一款功能強大的文字處理工具,用於過濾和轉換文字。它非常適合批量修改、自動化配置更改、清理日誌、提取資料以及整合到 shell 腳本中。
與文字編輯器不同,sed 編輯的是流,即從文件或命令流出的資料——這使得它非常適合管道和非互動式操作。
SED 作品:流模型和核心語法
基本語法
SED逐行處理輸入,對每一行符合位址或模式的行套用指令,並輸出結果。一般形式:
sed [OPTIONS] 'address(es) command(s)' file(s)
# Common usage examples
sed 's/old/new/' file.txt # Replace first 'old' on each line
sed -n '1,10p' file.txt # Print only lines 1 through 10
sed '/error/d' app.log # Delete lines that match 'error'
- -n: 抑制自動列印(與 p 一起使用以控制輸出)
- -i[後綴]: 就地編輯檔案(可選擇新增備份後綴,例如 -i.bak)
- -和: 使用擴展正規表示式(優於傳統的 -r)
- -f script.sed: 從文件中載入命令
- -e 'cmd': 內聯添加多個命令
地址和範圍
位址功能可讓您定位特定行。您可以使用行號、正規表示式模式或範圍:
# Line numbers
sed -n '5p' file # Print line 5
sed -n '5,12p' file # Print lines 5 through 12
# Regex addresses (delimited by /.../)
sed -n '/ERROR/p' log # Print lines containing 'ERROR'
sed '/^#/d' config # Delete commented lines
# Mixed ranges and address negation
sed '/START/,/END/p' file # Print between lines matching START and END
sed '/^$/!p' file # Print all non-empty lines (! negates the address)
常用SED指令及實際範例
選擇並列印行(p、-n、q、=)
# Print only matching lines (-n + p)
sed -n '/nginx/p' /etc/nginx/nginx.conf
# Show line numbers for matches
sed -n '/PermitRootLogin/=' /etc/ssh/sshd_config
# Stop after first match (faster on huge files)
sed '/CRITICAL/q' app.log
尋找並取代文字 (s///)
取代指令 s/regex/repl/flags 會尋找符合項目並進行取代。使用不同的分隔符號可以避免大量的轉義。
# Replace first match per line
sed 's/foo/bar/' file
# Replace all matches per line (global)
sed 's/foo/bar/g' file
# Case-insensitive replace (GNU sed)
sed 's/linux/Linux/Ig' notes.txt
# Use an alternate delimiter to avoid escaping slashes (e.g., paths)
sed 's#/var/www/html#/srv/www#' vhost.conf
# Replace only on lines that match an address
sed '/^server_name/s/example.com/example.org/' site.conf
# Replace only the 2nd occurrence per line
sed 's/foo/bar/2' input.txt
# Use captured groups and the & (whole match)
sed -E 's/([0-9]{3})-([0-9]{2})-([0-9]{4})/***-**-3/g' data.txt
sed -E 's/error:<([^>]+)>/issue:&[1]/' log.txt
插入、追加和更改行(i、a、c)
# Insert a line before matches
sed '/^[mysqld]/i # Managed by automation' my.cnf
# Append a line after matches
sed '/listen 80;/a listen 443 ssl;' nginx.conf
# Change matching lines entirely
sed '/^DocumentRoot/c DocumentRoot "/srv/www/example"' httpd.conf
刪除行 (d)
# Remove comments and empty lines
sed -E '/^s*($|#)/d' file
# Delete a known range
sed '10,20d' file
# Delete everything outside a block (negate the range)
sed '/BEGIN/,/END/!d' file
一次運行中多次編輯(-e、;、-f)
# Chain commands with -e
sed -E -e 's/s+$//' -e 's/^s+//' input.txt
# Or separate with semicolons
sed -E 's/s+$//; s/^s+//' input.txt
# Load from a script file
sed -f fixup.sed input.txt
# Example fixup.sed:
# s/localhost/127.0.0.1/g
# /^#/d
# /^s*$/d
安全地進行原地編輯 (-i) 和可移植性提示
直接編輯檔案雖然方便,但如果忽略備份則風險很高。建議先進行試運行,然後再進行原地編輯,並加入備份後綴。
# Dry run: preview changes
sed -E 's/http:/https:/g' site.conf | diff -u site.conf -
# Linux (GNU sed): create a backup
sed -i.bak 's/PermitRootLogin no/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
# macOS/BSD sed: empty string means no backup
sed -i '' -E 's#<Directory /var/www>#<Directory /srv/www>#' httpd.conf
便攜性注意事項:
- 使用 -E 參數可以啟用擴充正規表示式。在舊版 GNU sed 系統中,-r 參數也適用;但在 BSD/macOS 系統中,建議使用 -E 參數。
- 不區分大小寫的標誌 I 是 GNU sed 指令。為了確保可移植性,請預先規範化大小寫或使用字元類別。
- macOS 需要使用 -i ” 來停用備份;GNU sed 接受不含參數的 -i。
高階 SED:正規表示式、多行和保留空格
擴展正規表示式和反向引用
使用 -E 參數,您可以獲得現代正規表示式功能,例如 +、?、| 以及無需反斜線的分組。反向引用允許您在替換中重複使用捕獲的分組。 & 符號會展開為整個匹配項。
# Normalize repeated whitespace to a single space
sed -E 's/[[:space:]]+/ /g' file
# Swap first and last name
sed -E 's/^([A-Za-z]+)s+([A-Za-z]+)$/2 1/' names.txt
# Keep only digits from each line
sed -E 's/[^0-9]+//g' data.txt
多行編輯 (N) 和行連接
預設情況下,sed 指令逐行執行。使用 N 參數可將下一行新增至模式空間,從而跨行執行操作。
# Join pairs of lines with a space
sed 'N; s/n/ /' file
# Remove blank lines that follow another blank line (collapse multiple blanks)
sed -E ':a; /^s*$/N; s/^s*n+/n/; ta' file
# Replace a token that may be split across two lines
sed 'N; s/TOKENnCONTINUED/TOKEN CONTINUED/; P; D' file
空白鍵技巧(h、H、g、G、x)
SED 有兩個緩衝區:模式空間(目前線路)和保持空間(暫存區)。在它們之間移動資料可以實現更高級的邏輯。
# Print each line along with the previous line
sed '1!G; h; $!p' file
# Swap current and previous lines
sed 'x; 1!p; h' file
分支和條件替換(b,t)
使用標籤分支來建立條件流。 t 指令僅在成功發生替換時才會分支。
# If we replaced 'alpha', also replace 'beta' on the same line
sed -E ':start; s/alpha/A/g; t next; b end; :next s/beta/B/g; :end' file
面向系統管理員和DevOps的實際SED單行命令
這些實用範例解決了伺服器上和 CI/CD管線中的常見任務。
1)從設定檔中移除註解和尾隨空格:
sed -E 's/s+$//; /^s*($|#)/d' config.conf2) 批次 HTTPS 升級 Nginx 虛擬主機:
find /etc/nginx/sites-available -type f -name '*.conf' -print0
| xargs -0 sed -i.bak 's/http:/https:/g'3)輪換日誌,保留最後 1000 行:
sed -n -e :a -e '$q;N;101,$D;ba' app.log > app.log.tail4)在日誌中對電子郵件使用者名稱進行隱私屏蔽:
sed -E 's/([A-Za-z0-9._%+-])[A-Za-z0-9._%+-]*(@[A-Za-z0-9.-]+.[A-Za-z]{2,})/1***2/g' access.log5) 將 CSV 分隔符號從逗號轉換為製表符(不要在引號內轉換-保持簡單):
sed 's/,/t/g' data.csv > data.tsv6) 僅在特定程式碼區塊內更新鍵的值:
sed -E '/<VirtualHost *:80>/, /</VirtualHost>/ s/ServerName .*/ServerName example.org/' vhost.conf7) 刪除重複的相鄰行(簡單去重):
sed '$!N; /^(.*)n1$/!P; D' fileSED、awk 和 grep:何時使用哪一個?
- 使用 grep 指令按模式過濾文字行。它速度快、操作簡單,最適合純粹的配對。
- 使用 sed 轉換文字流:尋找/取代、刪除/插入行、小型邏輯和快速單行命令。
- 使用 awk 進行列感知處理、計算和結構化輸出(例如 CSV/TSV 報告)。
在許多管道中,你會將它們組合起來:grep 縮小數據範圍,sed 清理/格式化數據,awk 聚合或計算數據。
性能和最佳實踐
- 在進行原地編輯之前,請使用 -n 和 -p 參數進行測試。結合 diff 參數進行對比,以增強置信度。
- 使用單引號將命令括起來以防止 shell 擴展:'s/$HOME/…/' 而不是 “s/$HOME/…/”。
- 選擇智慧分隔符號(| # ~)以避免轉義路徑和 URL 中的斜線。
- 使用 ^ 和 $ 進行錨定模式,以減少誤報並加快匹配速度。
- 建議使用 -E 選項以獲得更清晰的正規表示式語法。保持表達式的可讀性。
- 對於大型作業,將規則儲存在 .sed 檔案中(使用 -f 參數)。這可以提高可維護性和速度。
- 當不需要Unicode規則時,設定LC_ALL=C可以加快逐字節處理速度。
- 注意可移植性:GNU 與 BSD 在 -i 和正規表示式標誌方面存在差異。
在測試伺服器上安全練習
使用 sed 批次編輯配置或日誌時,請先在測試環境中進行測試。 YouStable VPS,您將獲得完整的root權限、快照備份和 SSH 開箱即用—因此您可以試用 sed 單行命令,立即回滾,並自信地將變更推送到生產環境。這很簡單 避免在生產伺服器上進行危險編輯的方法.
SED 速查表:你每天都會用到的指令
- 打印: -n 'addr p' 文件
- 尋找並取代: 's/old/new/g'
- 刪除: 'addr d'
- 插入/追加: 'addr i text' / 'addr a text'
- 更改線路: 'addr c 文本'
- 行號: '='
- 多條命令: -e 'cmd1' -e 'cmd2' 或 'cmd1; cmd2'
- 擴展正規表示式: -E
- 就地編輯: -i[.bak]
常見的陷阱以及如何避免它們
- 意外的全球變遷: 先縮小範圍,然後再擴大範圍。
- 引用問題: 使用單引號;只轉義 sed 所需的部分。
- 無備份覆蓋: 請務必使用 -i.bak 或版本控制。
- 正規表示式貪婪度: 使用錨點和字元類別進行精確匹配。
- 平台不符: macOS 與 GNU/Linux 系統上 -i 和正規表示式標誌的調整。
常見問題
Linux 系統中 SED 指令是做什麼用的?
SED 是一款串流編輯器,可自動執行文字轉換,例如尋找和取代、刪除或插入行以及格式化。它廣泛應用於 shell 腳本、CI/CD 管線、日誌清理和配置中。 manage之所以說它好,是因為它速度快、可編寫腳本,而且無需打開編輯器即可逐行運行。
如何使用 SED 遞歸地替換所有文件中的文字?
將 find 指令與 sed -i 指令結合使用,可以安全地進行遞歸編輯:
查找 . -type f -name '*.conf' -print0 \
| xargs -0 sed -i.bak 's/old.domain/new.domain/g'
此操作會將每個檔案備份為 .bak 檔案。刪除備份檔案之前,請使用 git diff 或 diff 指令檢查變更。
GNU SED 和 BSD/macOS SED 有什麼不同?
主要區別包括原地編輯語法(macOS 上的 -i ” 與 GNU 上的 -i)和一些標誌(GNU 支援 I 表示不區分大小寫的 s///)。擴展正則表達式在 BSD/macOS 上是 -E,現代 GNU sed 也支持。編寫跨平台腳本時,請測試其可移植性。
如何在不建立備份的情況下直接編輯文件?
在 GNU/Linux 系統上,使用不含後綴的 -i 參數。在 macOS/BSD 系統上,傳遞一個空字串:
# GNU/Linux
sed -i 's/http:/https:/g' 文件
# macOS/BSD
sed -i ”'s/http:/https:/g' 文件
如何在 SED 中使用擴展正規表示式?
使用 -E 啟用擴充正規表示式,以便您可以編寫更簡潔的模式,而無需過多轉義:
sed -E 's/([A-Za-z]+)\s+([A-Za-z]+)/\2 \1/' 名稱.txt
如何只替換一行中的第 n 個匹配項?
將出現次數作為標誌加入 s 指令。此範例僅替換每行中的第二個實例:
使用 sed 指令執行 's/error/warning/2' 日誌。
對於簡單的替換操作,SED 比 awk 或 Python 更快嗎?
對於基本的查找替換或行過濾任務,由於啟動開銷極小且採用串流執行,sed 通常比 awk 或 Python 更快、佔用記憶體更少。但對於結構化解析或計算,儘管性能有所妥協,awk/Python 可能更合適。
結語
掌握這些技巧和最佳實踐,您就可以自信地使用SED。 Linux 中的指令 用於自動化文字處理、重構配置和簡化伺服器工作流程。如果您想要一個具有快照和完整功能的安全測試環境。 SSH考慮在以下情況下進行測試: YouStable VPS 在將變更投入生產之前。
