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.

SysOps·37 commands·Last updated 2026-07-21

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/' file
Replace first match per line
sed 's/old/new/g' file
Replace all matches (global)
sed 's/old/new/2' file
Replace the 2nd match per line
sed 's/old/new/I' file
Case-insensitive match
sed -i 's/old/new/g' file
Edit the file in place
sed -i.bak 's/old/new/g' file
Edit and back up the original
sed 's/\/path\/old/path\/new/g' file
Escape slashes when replacing paths
sed 's|old|new|g' file
Use | as delimiter to avoid escaping slashes

Delete 7

sed '5d' file
Delete line 5
sed '5,10d' file
Delete lines 5-10
sed '/pattern/d' file
Delete matching lines
sed '/^$/d' file
Delete blank lines
sed '/^#/d' file
Delete comment lines
sed '$d' file
Delete the last line
sed '1d;$d' file
Delete the first and last lines

Insert & Append 5

sed '5i\new text' file
Insert before line 5
sed '5a\new text' file
Append after line 5
sed '/pattern/i\new text' file
Insert before matching lines
sed '/pattern/a\new text' file
Append after matching lines
sed '5i\line1\nline2' file
Insert multiple lines

Print 5

sed -n '5p' file
Print only line 5
sed -n '5,10p' file
Print only lines 5-10
sed -n '/pattern/p' file
Print only matching lines
sed -n '1p;$p' file
Print first and last lines
sed 's/old/new/p' file
Substitute and print changed lines

Regular Expression 7

sed 's/^prefix/new/' file
Match line start
sed 's/suffix$/new/' file
Match line end
sed 's/\<word\>/new/g' file
Match word boundary
sed 's/[0-9]/X/g' file
Match digits
sed 's/[^0-9]/X/g' file
Match non-digits
sed 's/\(pattern\)/\1/g' file
Capture group and backreference
sed -E 's/(old)/\1-new/g' file
Extended regex (-E or -r)

Multi-line 5

sed ':a;N;$!ba;s/\n//g' file
Delete all newlines
sed 'N;s/\n/ /'
Merge adjacent two lines
sed '/start/,/end/s/old/new/g' file
Substitute within a range
sed '/start/,/end/d' file
Delete lines within a range
sed '/start/,/end/p' file
Print lines within a range

Parameter matrix

ParameterEffectExample
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. 1改文件前先预览结果

    sed 's/old/new/g' config.yaml

    不带 -i 只输出;确认无误后再加 -i.bak 落盘。

  2. 2原地修改并保留备份

    sed -i.bak 's/old/new/g' f.txt

    生成 f.txt.bak,出问题可立即回滚。

  3. 3清理注释与空行

    sed '/^#/d; /^$/d' nginx.conf

    多条命令用分号分隔,一次扫描完成。

  4. 4只在指定范围内替换

    sed '/start/,/end/s/old/new/g' file

    范围模式 /start/,/end/ 可用于删除、替换与打印。

  5. 5macOS 上的原地编辑

    sed -i '' 's/old/new/g' file

    BSD 版 -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.txt

N 把下一行读进模式空间,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