Linux sed 命令
最后修改于 2025 年 4 月 2 日
sed (stream editor) 命令是 Linux 中一个强大的文本处理工具,它对输入流执行基本和高级的文本转换。它逐行读取文本,应用指定的命令,并输出结果。本指南通过 20 个实用示例介绍 sed 的基础知识,涵盖从基本替换到高级文本操作。掌握 sed 可以无需手动干预即可高效地批量编辑文件和流。
基本 sed 语法
sed 的基本语法是 sed [options] 'commands' [input-file]。Sed 对输入的每一行进行操作,应用一个或多个编辑命令。默认情况下,sed 会输出到 stdout,而不修改输入文件。本示例展示了基本的 sed 用法模式。
# 1. Simple text substitution (replace first occurrence per line) echo "hello world" | sed 's/hello/hi/' # Output: hi world # 2. Editing file in-place (with backup) sed -i.bak 's/foo/bar/' file.txt # 3. Multiple commands echo "hello world" | sed -e 's/hello/hi/' -e 's/world/there/' # Output: hi there # 4. Using different delimiters echo "path/to/file" | sed 's|/|_|g' # Output: path_to_file # 5. Print only modified lines (-n with p flag) seq 1 5 | sed -n 's/3/three/p' # Output: three
示例 1 展示了基本的替换语法 s/pattern/replacement/。示例 2 使用 `-i` (in-place) 选项和备份文件进行就地文件编辑。示例 3 使用 -e 组合多个命令。示例 4 使用替代分隔符以提高可读性。示例 5 展示了如何抑制默认输出并仅打印修改后的行。
文本替换示例
替换是 sed 最常见的操作,使用 s 命令。这些示例使用不同的标志和模式演示了各种替换技术。掌握替换可以实现强大的文本转换。
# 6. Global replacement (all occurrences) echo "hello hello world" | sed 's/hello/hi/g' # Output: hi hi world # 7. Replace only 2nd occurrence echo "one two two three" | sed 's/two/2/2' # Output: one two 2 three # 8. Case-insensitive substitution echo "Hello hello HELLO" | sed 's/hello/hi/i' # Output: hi hello HELLO # 9. Using groups in replacement echo "John Doe" | sed 's/\([^ ]*\) \([^ ]*\)/\2, \1/' # Output: Doe, John # 10. Using & in replacement (matched pattern) echo "123 abc" | sed 's/[0-9]*/& &/' # Output: 123 123 abc
示例 6 显示了带有 g 标志的全局替换。示例 7 仅替换第二个匹配项。示例 8 使用 i 进行不区分大小写的匹配。示例 9 使用分组重新排序名称。示例 10 展示了 & 如何代表匹配的文本。
行选择和删除
Sed 可以在应用操作之前按行号或模式选择特定行。这些示例演示了行寻址和删除技术。精确的行选择对于目标文本处理至关重要。
# 11. Delete lines containing pattern seq 1 5 | sed '/3/d' # Output: 1 2 4 5 # 12. Delete lines NOT containing pattern seq 1 5 | sed '/3/!d' # Output: 3 # 13. Delete specific line number seq 1 5 | sed '3d' # Output: 1 2 4 5 # 14. Delete range of lines (2-4) seq 1 5 | sed '2,4d' # Output: 1 5 # 15. Delete from line to end of file seq 1 5 | sed '3,$d' # Output: 1 2
示例 11 删除匹配模式的行。示例 12 使用 ! 反转匹配。示例 13 按行号删除。示例 14 显示范围删除。示例 15 删除从第 3 行到末尾 ($) 的行。
高级转换
Sed 支持高级文本转换,包括多行操作、暂存区 (hold space) 操作和条件执行。这些示例演示了 sed 在复杂任务中的强大编辑功能。
# 16. Append text after match
echo -e "line1\nline2" | sed '/line1/a\appended text'
# Output:
# line1
# appended text
# line2
# 17. Insert text before match
echo -e "line1\nline2" | sed '/line2/i\inserted text'
# Output:
# line1
# inserted text
# line2
# 18. Change entire line
echo -e "old1\nold2" | sed '/old1/c\new line'
# Output:
# new line
# old2
# 19. Transform specific characters (like tr)
echo "hello" | sed 'y/abcdefghij/0123456789/'
# Output: 74llo
# 20. Multi-line pattern matching (N command)
echo -e "line1\nline2\nline3" | sed '/line1/{N;s/line1\nline2/replaced/}'
# Output:
# replaced
# line3
示例 16 在匹配项后追加文本。示例 17 在匹配项前插入文本。示例 18 替换整行。示例 19 转换字符,类似 tr。示例 20 使用 N 命令演示多行操作。
实用的 sed 脚本
这些实用示例使用 sed 解决了现实世界的文本处理问题。它们结合了多种技术,以展示 sed 在生产环境中的多功能性。
# 21. Remove blank lines echo -e "line1\n\nline2" | sed '/^$/d' # Output: # line1 # line2 # 22. Remove leading whitespace echo " text" | sed 's/^[ \t]*//' # Output: text # 23. Remove trailing whitespace echo "text " | sed 's/[ \t]*$//' # Output: text # 24. Remove HTML tags echo "<p>Hello <b>world</b></p>" | sed 's/<[^>]*>//g' # Output: Hello world # 25. Number lines (like nl) echo -e "one\ntwo\nthree" | sed '=' | sed 'N;s/\n/ /' # Output: # 1 one # 2 two # 3 three
示例 21 删除空行。示例 22-23 修剪空白。示例 24 删除 HTML 标签。示例 25 通过组合两个 sed 命令对行进行编号。
sed 与正则表达式
Sed 的真正强大之处在于将其命令与正则表达式结合。这些示例演示了复杂的模式匹配和替换技术。
# 26. Match whole words only
echo "cart part smart" | sed 's/\bpart\b/replace/g'
# Output: cart replace smart
# 27. Extract text between patterns
echo "before [extract] after" | sed 's/.*\[\([^]]*\)\].*/\1/'
# Output: extract
# 28. Convert DOS line endings (CRLF to LF)
sed 's/\r$//' dosfile.txt > unixfile.txt
# 29. Convert lowercase to uppercase
echo "hello" | sed 's/.*/\U&/'
# Output: HELLO
# 30. Format phone numbers
echo "Call 1234567890" | sed 's/\([0-9]\{3\}\)\([0-9]\{3\}\)\([0-9]\{4\}\)/(\1) \2-\3/'
# Output: Call (123) 456-7890
示例 26 匹配整个单词。示例 27 提取括号之间的文本。示例 28 转换行结束符。示例 29 将文本转换为大写。示例 30 使用捕获组格式化电话号码。
sed 分支和流程控制
Sed 提供了分支命令,用于在编辑脚本中实现复杂的流程控制。这些示例演示了 sed 中的条件操作和循环。
# 31. Skip lines containing pattern
echo -e "include\nskip\ninclude" | sed '/skip/b; s/include/replaced/'
# Output:
# replaced
# skip
# replaced
# 32. Multiple commands on matched lines
echo -e "line1\nspecial\nline2" | sed '/special/{s/line/xxx/;p;d}'
# Output:
# line1
# xxxspecial
# line2
# 33. Conditional replacement (only if another match exists)
sed '/start/,/end/ s/foo/bar/' file.txt
# 34. Label and branch example
echo -e "a\nb\na\nc" | sed ':top; /a/{s/a/x/; b top}'
# Output:
# x
# b
# x
# c
# 35. Quit after first match
seq 1 10 | sed '/5/q'
# Output: 1 2 3 4 5
示例 31 跳过匹配行的处理。示例 32 对匹配项应用多个命令。示例 33 显示基于范围的替换。示例 34 演示标签和分支。示例 35 在第一次匹配后退出。
sed 暂存区和模式空间
Sed 维护一个模式空间(当前行)和一个暂存区(临时存储)以进行高级文本操作。这些示例演示了多行处理技术。
# 36. Reverse file lines (tac) seq 1 3 | sed '1!G;h;$!d' # Output: # 3 # 2 # 1 # 37. Double space lines echo -e "a\nb\nc" | sed 'G' # Output: # a # # b # # c # 38. Join pairs of lines echo -e "a\nb\nc\nd" | sed 'N;s/\n/ /' # Output: # a b # c d # 39. Print duplicate lines only echo -e "a\nb\na\nc" | sed -n '$!N; /^\(.*\)\n\1$/p; D' # Output: a # 40. Number non-empty lines echo -e "a\n\nb\nc" | sed '/./=' | sed '/./N; s/\n/ /' # Output: # 1 a # 3 b # 4 c
示例 36 反转文件行。示例 37 双倍行距。示例 38 连接行对。示例 39 查找重复项。示例 40 只对非空行进行编号。这些示例展示了 sed 的高级缓冲区操作。
最佳实践
在将 sed 命令应用于重要文件之前,请先使用示例输入进行测试。对于复杂的脚本,请使用 -e 以提高可读性。在开发过程中,请在就地编辑 (-i) 前使用备份。为了方便将来维护,请使用 # 为复杂的 sed 脚本添加注释。对于极其复杂的文本处理任务,请考虑使用 perl 或 awk。
资料来源
从这些资源中了解更多信息:GNU sed 手册、sed 手册页,以及sed & awk 书籍。
作者
我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有超过十年的经验。