sed Cheatsheet - Linux Text Editing Reference
sed has two pillars: the s/// substitution and the address that decides which lines it applies to, and combining them expresses "change this fragment only inside those lines". The sheet maps onto six recurring tasks — bulk-editing config values, dropping blank or comment lines, inserting before or after a line, printing only matches, writing regular expressions that mean what you intended, and flattening multi-line structures. The thing worth defending against is an unrecoverable mistake: sed -i rewrites the original with no confirmation, so run once without -i, read the output, then commit with -i.bak. The regex group hides a dialect trap — both BSD and GNU sed default to BRE, where +, ? and | must be escaped or you switch with -E. The division of labour is simple: sed rewrites content, awk reshapes structure, grep filters lines; and macOS sed -i demands a backup suffix while Linux accepts a bare -i.
Typical Use Case
For developers who need to rewrite configuration files in bulk. The risk in sed concentrates on irreversibility: -i edits in place with no undo, and the / delimiter collides with paths inside the pattern. This sheet is organised into six groups — substitution, deletion, insertion, printing, regular expressions and multi-line operations. Three pieces of advice matter most: use -i.bak so there is a backup, switch the delimiter to | when the pattern contains slashes, and always preview once without -i before writing to disk.
Substitute 8
sed 's/old/new/' filesed 's/old/new/g' filesed 's/old/new/2' filesed 's/old/new/I' filesed -i 's/old/new/g' filesed -i.bak 's/old/new/g' filesed 's/\/path\/old/path\/new/g' filesed 's|old|new|g' fileDelete 7
sed '5d' filesed '5,10d' filesed '/pattern/d' filesed '/^$/d' filesed '/^#/d' filesed '$d' filesed '1d;$d' fileInsert & Append 5
sed '5i\new text' filesed '5a\new text' filesed '/pattern/i\new text' filesed '/pattern/a\new text' filesed '5i\line1\nline2' filePrint 5
sed -n '5p' filesed -n '5,10p' filesed -n '/pattern/p' filesed -n '1p;$p' filesed 's/old/new/p' fileRegular Expression 7
sed 's/^prefix/new/' filesed 's/suffix$/new/' filesed 's/\<word\>/new/g' filesed 's/[0-9]/X/g' filesed 's/[^0-9]/X/g' filesed 's/\(pattern\)/\1/g' filesed -E 's/(old)/\1-new/g' fileMulti-line 5
sed ':a;N;$!ba;s/\n//g' filesed 'N;s/\n/ /'sed '/start/,/end/s/old/new/g' filesed '/start/,/end/d' filesed '/start/,/end/p' fileParameter matrix
| Parameter | Effect | Example |
|---|---|---|
s/// | 替换每行第一个匹配 | sed 's/old/new/' file |
/g | 全局替换该行所有匹配 | sed 's/old/new/g' file |
/2 | 只替换每行第 2 个匹配 | sed 's/old/new/2' file |
/I | 忽略大小写匹配 | sed 's/old/new/I' file |
-i | 原地编辑(无备份,不可撤销) | sed -i 's/old/new/g' file |
-i.bak | 原地编辑并保留 .bak 备份 | sed -i.bak 's/old/new/g' file |
自定义分隔符 | | 模式含 / 时免转义 | sed 's|/old/|/new/|g' file |
Nd / 'N,Md' | 删除第 N 行 / 第 N 到 M 行 | sed '5,10d' file |
/pat/d | 删除匹配模式的行 | sed '/^#/d' config |
Ni / Na | 在第 N 行前插入 / 后追加 | sed '5a\new text' file |
-n "Np" | 只打印指定行(不自动输出) | sed -n '5,10p' file |
/start/,/end/s/// | 只在指定范围内替换 | sed '/start/,/end/s/old/new/g' file |
\( \) 与 \1 | 捕获组与反向引用(BRE) | sed 's/\(pattern\)/\1/g' file |
-E | 扩展正则,( ) 无需转义 | sed -E 's/(old)/\1-new/g' file |
N;$!ba;s/\n//g | 删除所有换行符合并全文 | sed ':a;N;$!ba;s/\n//g' file |
Common pitfalls
Symptom替换含路径的字符串后 sed 报错或结果为空。
Cause分隔符 / 与模式中的路径冲突,需要大量转义。
Fix换用其它分隔符:sed "s|/old/path|/new/path|g" file。
Symptomsed -i 改完文件后内容全空了,无法恢复。
Cause模式匹配范围比预期大(如 .* 贪婪匹配整行),且 -i 没有备份。
Fix改用 -i.bak 留备份;执行前先不带 -i 看输出确认。
Symptom只想替换每行第一次出现,结果全被替换了。
Cause模式里写了 g 标志,或把 . 当成通配导致匹配多处。
Fix去掉 g;字面匹配用 . 转义成 \. 或改用 grep -F 先确认匹配数。
SymptommacOS 上 sed -i 报错或文件被清空。
CauseBSD 版 sed 的 -i 必须跟备份后缀,不能直接 -i。
FixmacOS 用 sed -i "" "s/old/new/g" file,或 sed -i.bak(会自动生成 .bak)。
Symptom反向引用 \1 输出为空或保留了原样。
CauseBRE 下捕获组必须写成 \( \),且替换串里写 \1。
Fix改用 -E 简化写法:sed -E "s/(old)/\1-new/g" file。
Symptom删除注释行时把含 # 的正文也删了。
Cause/^#/ 只匹配行首是 # 的行,若写成 /#/ 则会删掉所有含 # 的行。
Fix用锚定写法 sed "/^#/d";确认后先不带 -d 的 -n 打印查看匹配范围。
Symptom在 macOS/BSD 与 GNU 之间来回切换,命令行为不一致。
Cause两者的 -i、-E 语法与部分扩展选项存在差异。
Fix统一用 -E 与 -i.bak 写法,两个平台都能工作;避免依赖 BSD 特有选项。
Troubleshooting
1改文件前先预览结果
sed 's/old/new/g' config.yaml不带 -i 只输出;确认无误后再加 -i.bak 落盘。
2原地修改并保留备份
sed -i.bak 's/old/new/g' f.txt生成 f.txt.bak,出问题可立即回滚。
3清理注释与空行
sed '/^#/d; /^$/d' nginx.conf多条命令用分号分隔,一次扫描完成。
4只在指定范围内替换
sed '/start/,/end/s/old/new/g' file范围模式 /start/,/end/ 可用于删除、替换与打印。
5macOS 上的原地编辑
sed -i '' 's/old/new/g' fileBSD 版 -i 必须带后缀,空串表示不备份;要备份用 -i.bak。
Command Examples
Dry-run a substitution, then edit in place with a backup
sed 's/localhost/0.0.0.0/g' config.yaml
sed -i.bak 's/localhost/0.0.0.0/g' config.yaml第一行不带 -i 只输出,确认无误后第二行用 -i.bak 落盘并留下 .bak。含 / 的模式把分隔符换成 # 更省心。
Output
server: 0.0.0.0 bind: 0.0.0.0:8080 url: http://localhost/api
Substitute within a range of markers
sed '/# BEGIN/,/# END/s/old/new/g' config.ini地址区间 /start/,/end/ 限定作用范围,避免误改区块外的同名内容。删除区间用 sed '/start/,/end/d'。
Output
managed-by-tool
Join adjacent lines
sed -n 'N;s/\n/ /;P;D' data.txtN 把下一行读进模式空间,s 把换行换成空格。sed 的多行处理语法较绕,简单的连续行合并也可以用 paste -sd ' ' 更直观。
Output
first line second line
Common Pitfalls
- sed -i has no undo and no backup; verify without -i first, then use -i.bak.
- sed defaults to BRE where \+ \| and \( are not special; add -r for extended regular expressions.
- A pattern containing / collides with the delimiter — switch to # or |.
- A range deletion like sed '/start/,/end/d' runs to end of file when the end marker is missing.
- sed is a stream editor, not a logic engine; reach for awk or a script when the transformation is conditional.
Tips
- Before editing in place with sed -i, back up first (-i.bak), or preview without -i.
- sed uses BRE (basic regex) by default; +, ?, | must be escaped or enable ERE with -E.
- On macOS, sed -i requires a backup suffix (e.g. -i ""); on Linux -i works directly.
FAQ
What happens if I omit the g flag in a sed substitution?
Without g, sed replaces only the first match on each line. Given a line with three occurrences of old, sed 's/old/new/' changes just the first and leaves the rest untouched — you must write s/old/new/g to replace them all. That restraint is occasionally useful, for example when you only want to rewrite the first port number in a URL.
How do I operate on a range of lines with sed?
Use Np or a range: sed -n '5,10p' file prints lines 5 through 10, and sed '5,10d' file deletes them. The pattern form sed '/start/,/end/d' file removes everything between the line matching start and the line matching end. Pattern-based ranges are more robust than line numbers for files with irregular structure.
What do the s, d, i and a commands do in sed?
s substitutes matched text in place. d deletes the whole line. i inserts before a matching line, and a appends after it. The key difference is that s keeps the line and changes content, d discards it entirely, and i/a increase the line count. They combine with semicolons: sed '/^#/d; /^$/d' nginx.conf strips comment lines and blank lines in one pass.
Can sed work across lines?
Yes, though the syntax takes a moment. N appends the next line to the pattern space, so N followed by s/\n/ / merges two lines into one; the inverse, sed ':a;N;$!ba;s/\n//g' file, strips every newline and collapses the file to a single line. GNU sed also has -z so N splits on NUL instead of newline, which helps for compressed blobs that contain no newlines.
Why does my sed regex sometimes not take effect?
Most often it is delimiter collision: if the script uses / and your pattern also contains /, as URLs do, you must switch delimiters, e.g. s#https://x#http://y#. Also remember sed defaults to BRE, where \+ \| and \( are not special — write BRE syntax or add -r to switch to extended regular expressions.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 21, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us