sed 命令详解#

sed(Stream Editor)是 Linux 系统中强大的流编辑器,用于对文本进行过滤和转换。它支持正则表达式,可以高效地处理大文件,是文本处理和自动化脚本的重要工具。

入门#

基本用法#

# 基本替换
sed 's/old/new/' filename.txt

# 删除行
sed 'd' filename.txt

# 打印特定行
sed -n '10p' filename.txt

# 从标准输入处理
echo "text" | sed 's/text/TEXT/'

常用选项#

选项说明
-e执行多个脚本
-f从文件读取脚本
-n静默模式,只输出匹配的行
-i直接修改文件
-r使用扩展正则表达式
-E使用扩展正则表达式(BSD)

基本示例#

# 替换文本
sed 's/hello/world/' filename.txt

# 删除行
sed '5d' filename.txt

# 打印特定行
sed -n '10,20p' filename.txt

# 在文件中替换
sed -i 's/old/new/' filename.txt

中级#

替换操作#

# 基本替换
sed 's/old/new/' filename.txt

# 全局替换
sed 's/old/new/g' filename.txt

# 替换第N次出现
sed 's/old/new/2' filename.txt

# 忽略大小写替换
sed 's/old/new/gI' filename.txt

# 删除匹配的文本
sed 's/pattern//g' filename.txt

删除操作#

# 删除特定行
sed '5d' filename.txt

# 删除范围行
sed '10,20d' filename.txt

# 删除匹配的行
sed '/pattern/d' filename.txt

# 删除空行
sed '/^$/d' filename.txt

# 删除注释行
sed '/^#/d' filename.txt

插入和追加#

# 在行前插入
sed '5i\new line' filename.txt

# 在行后追加
sed '5a\new line' filename.txt

# 在匹配行前插入
sed '/pattern/i\new line' filename.txt

# 在匹配行后追加
sed '/pattern/a\new line' filename.txt

# 插入多行
sed '5i\line1\nline2\nline3' filename.txt

打印操作#

# 打印特定行
sed -n '10p' filename.txt

# 打印范围行
sed -n '10,20p' filename.txt

# 打印匹配的行
sed -n '/pattern/p' filename.txt

# 打印奇数行
sed -n '1~2p' filename.txt

# 打印偶数行
sed -n '2~2p' filename.txt

高级#

正则表达式#

# 使用扩展正则表达式
sed -E 's/pattern1|pattern2/new/' filename.txt

# 匹配行首
sed 's/^pattern/new/' filename.txt

# 匹配行尾
sed 's/pattern$/new/' filename.txt

# 匹配单词边界
sed 's/\bpattern\b/new/' filename.txt

# 使用字符类
sed 's/[0-9]/X/g' filename.txt

高级替换#

# 使用捕获组
sed 's/\(pattern1\).*\(pattern2\)/\1 \2/' filename.txt

# 交换两个词
sed 's/\([a-z]*\) \([a-z]*\)/\2 \1/' filename.txt

# 使用 & 引用匹配的文本
sed 's/prefix/&suffix/' filename.txt

# 大小写转换
sed 's/\([a-z]\)/\u\1/g' filename.txt
sed 's/\([A-Z]\)/\l\1/g' filename.txt

多行操作#

# 合并连续行
sed 'N;s/\n/ /' filename.txt

# 删除连续空行
sed '/^$/N;/^\n$/D' filename.txt

# 匹配多行模式
sed '/start/,/end/d' filename.txt

# 在多行间插入文本
sed '/start/,/end/a\---' filename.txt

文件操作#

# 直接修改文件
sed -i 's/old/new/' filename.txt

# 创建备份
sed -i.bak 's/old/new/' filename.txt

# 读取文件内容
sed '10r insert.txt' filename.txt

# 将匹配行写入文件
sed '/pattern/w output.txt' filename.txt

大师#

复杂替换#

# 替换多个模式
sed -e 's/pattern1/new1/g' -e 's/pattern2/new2/g' filename.txt

# 条件替换
sed '/condition/s/old/new/' filename.txt

# 递归替换
sed ':a;s/pattern/replacement/;ta' filename.txt

# 智能缩进
sed 's/^/\t/' filename.txt

高级文本处理#

# 删除HTML标签
sed 's/<[^>]*>//g' filename.txt

# 提取URL
sed -n 's/.*href="\([^"]*\)".*/\1/p' filename.txt

# 提取邮箱地址
sed -n 's/.*\([a-zA-Z0-9._%+-]*@[a-zA-Z0-9.-]*\.[a-zA-Z]*\).*/\1/p' filename.txt

# 格式化数字
sed 's/\([0-9]\)\([0-9][0-9][0-9]\)/\1,\2/g' filename.txt

脚本文件#

# 创建sed脚本文件
cat > script.sed <<EOF
s/old/new/g
/pattern/d
10,20p
EOF

# 执行脚本
sed -f script.sed filename.txt

# 复杂脚本示例
cat > complex.sed <<EOF
# 删除空行
/^$/d

# 删除注释行
/^#/d

# 替换文本
s/foo/bar/g

# 在特定行插入
10i\--- Inserted line ---
EOF

与其他命令组合#

# 与grep组合
grep "pattern" filename.txt | sed 's/pattern/new/'

# 与awk组合
awk '{print $1}' filename.txt | sed 's/^/PREFIX_/'

# 与sort组合
sort filename.txt | sed 's/\t/,/g'

# 与cut组合
cut -f1 filename.txt | sed 's/$/SUFFIX/'

无敌#

高级技巧#

# 使用分支和标签
sed '/start/{:a;n;/end/!ba}' filename.txt

# 条件执行
sed '/pattern1/{s/old1/new1/;b};/pattern2/{s/old2/new2/}' filename.txt

# 循环处理
sed ':a;s/pattern/replacement/;ta' filename.txt

# 多文件处理
sed 's/old/new/' file1.txt file2.txt file3.txt

大文件处理#

# 分块处理大文件
split -l 1000000 largefile.txt chunk_
for chunk in chunk_*; do
    sed 's/old/new/' "$chunk" > "$chunk.processed"
done
cat chunk_*.processed > final_result.txt

# 使用管道处理
cat largefile.txt | sed 's/old/new/' > output.txt

# 并行处理
find . -name "*.txt" -exec sed -i 's/old/new/' {} \;

自动化工作流#

# 自动化文本处理
#!/bin/bash
INPUT_DIR="./input"
OUTPUT_DIR="./output"
mkdir -p "$OUTPUT_DIR"

for file in "$INPUT_DIR"/*.txt; do
    filename=$(basename "$file")
    sed -e 's/foo/bar/g' -e 's/baz/qux/g' "$file" > "$OUTPUT_DIR/$filename"
done

# 自动化日志清理
#!/bin/bash
LOG_DIR="/var/log"
DATE=$(date +%Y-%m-%d)

find "$LOG_DIR" -name "*$DATE*" -type f | while read log; do
    sed -i '/DEBUG/d' "$log"
    sed -i '/TRACE/d' "$log"
done

# 自动化配置更新
#!/bin/bash
CONFIG_FILE="/etc/app/config.conf"
sed -i 's/^old_value=.*/old_value=new_value/' "$CONFIG_FILE"
sed -i 's/^another_value=.*/another_value=updated/' "$CONFIG_FILE"

性能调优#

# 监控性能
time sed 's/old/new/g' largefile.txt

# 使用 strace 分析
strace -c sed 's/old/new/g' largefile.txt

# 使用 valgrind 分析内存
valgrind --tool=massif sed 's/old/new/g' largefile.txt

# 优化处理
sed -n 's/old/new/p' largefile.txt | sort -S 1G

高级应用场景#

# 批量重命名文件
ls *.txt | sed 's/\(.*\)\.txt/mv \1.txt \1.bak/' | sh

# 批量修改代码
find . -name "*.py" -exec sed -i 's/old_function/new_function/g' {} \;

# 数据清洗
sed -e 's/\s\+/ /g' -e 's/^ //g' -e 's/ $//g' data.txt

# 日志格式化
sed 's/\[.*\]//' log.txt | sed 's/ - / /g'

最佳实践#

1. 使用场景#

  • 文本替换和转换
  • 批量文件处理
  • 日志清理和分析
  • 配置文件修改

2. 性能优化#

  • 对于大文件,使用管道处理
  • 避免复杂的正则表达式
  • 合理使用 -n 选项
  • 使用脚本文件提高可读性

3. 代码风格#

  • 使用注释说明复杂操作
  • 将复杂操作分解为多个简单操作
  • 使用脚本文件管理复杂逻辑
  • 测试后再使用 -i 选项

4. 脚本集成#

  • 在脚本中使用管道组合命令
  • 处理错误和异常情况
  • 使用变量和参数化脚本
  • 添加日志和调试信息

5. 学习路径#

  • 先掌握基本替换和删除
  • 学习正则表达式
  • 掌握多行操作和高级替换
  • 学习脚本文件和自动化
  • 最后学习性能优化

常见问题#

Q: sed 和 awk 有什么区别?#

A: sed 是流编辑器,适合文本替换和转换;awk 是完整的编程语言,适合复杂的数据处理和分析。

Q: 如何在 sed 中使用特殊字符?#

A: 使用反斜杠转义特殊字符,如 sed 's/\./_/g' 替换点号。

Q: 如何在 sed 中使用变量?#

A: 使用双引号:sed "s/$old/$new/g" filename.txt

Q: 如何处理多行文本?#

A: 使用 N 命令读取多行,或使用模式范围:sed '/start/,/end/d' filename.txt

Q: 如何备份原文件?#

A: 使用 -i.bak 选项:sed -i.bak 's/old/new/' filename.txt

相关命令#

  • awk - 强大的文本处理语言
  • grep - 文本搜索
  • cut - 字段提取
  • tr - 字符转换
  • perl - 强大的文本处理语言