Linux shell sed 命令基础

sed(Stream EDitor)是 Linux/Unix 系统中一个非常强大且常用的流编辑器。它主要用于对文本进行过滤和转换,

即读取输入流(文件或管道),按照指定的命令进行处理,然后将结果输出

核心概念和工作原理

流式处理:sed 逐行处理文本,不会一次性将整个文件加载到内存中,因此非常适合处理大文件。

模式空间:sed 维护一个叫做"模式空间"的缓冲区。它读取一行文本到模式空间,在那里应用所有给定的命令,然后输出模式空间的内容(除非被特别抑制),接着处理下一行。

非交互式:与 vi 或 nano 不同,你通过命令行预先写好所有编辑指令,sed 自动执行,非常适合脚本操作。

基本语法

sed [选项] '命令' 输入文件

sed [选项] -e '命令1' -e '命令2' ... 输入文件 # 多个命令

sed [选项] -f 脚本文件 输入文件 # 从文件读取命令

常用选项

选项 全称 说明

-n --quiet, --silent 静默模式。默认情况下,sed 会输出所有行。加上 -n 后,只有被 p 命令处理过的行才会被显示。

-e --expression 指定要执行的命令,用于连接多个命令。

-i --in-place 直接修改文件(危险但强大)。通常建议用 -i.bak 先创建备份。

-r --regexp-extended 使用扩展正则表达式(ERE),而不是默认的基本正则表达式(BRE),功能更强,语法更简洁。

-f --file 从指定文件中读取 sed 脚本。

常用命令

命令必须跟在选项后面,用单引号括起来。

命令 语法 说明

替换 s/原模式/替换内容/标志 最常用的命令。将匹配"原模式"的文本替换为"替换内容"。

删除 d 删除模式空间中的当前行,立即开始下一轮循环。

打印 p 打印当前模式空间的内容。通常与 -n 选项一起使用。

行号 = 打印当前行的行号。

插入 i\文本 在指定行之前插入文本。

追加 a\文本 在指定行之后追加文本。

读文件 r 文件名 将指定文件的内容读取并插入到匹配行之后。

写文件 w 文件名 将匹配行的内容写入到指定文件中。

退出 q [退出码] 在处理到指定行后立即退出 sed。

转换 y/原字符集/新字符集/ 类似 tr 命令,进行字符一对一转换。

地址定界

sed 命令可以指定只对某些行进行操作,这就是地址定界。如果省略,则命令会应用于所有行。

n 一个数字,表示第 n 行。 sed -n '5p' file # 只打印第5行

n,m 从第 n 行到第 m 行。 sed '10,20d' file # 删除10到20行

n,+m 从第 n 行到第 n+m 行。 sed '5,+3d' file # 删除5到8行

最后一行。 sed 'd' file # 删除最后一行

/regex/ 匹配正则表达式 regex 的行。 sed '/^#/d' file # 删除所有注释行(以#开头)

addr1,addr2 从匹配 addr1 的行开始,到匹配 addr2 的行结束。 sed '/start/,/end/d' file # 删除从包含"start"到包含"end"的所有行

n~m 从第 n 行开始,步长为 m。 sed -n '1~2p' file # 打印所有奇数行(第1,3,5...行)

替换命令 (s///) 的详解和标志

s/pattern/replacement/flags

标志 说明

g 全局替换。一行中所有匹配项都会被替换,而不仅仅是第一个。

p 打印替换发生后的当前模式空间。通常与 -n 选项一起使用。

w 文件名 将成功替换的行写入到指定文件。

i 或 I 匹配 pattern 时忽略大小写。

数字 一个数字(如1,2),表示只替换第N个匹配项。

替换内容中的特殊字符:

&: 代表匹配到的整个内容。

\1, \2, ... \9: 代表正则表达式中用 \( 和 \) 分组的内容。

经典案例

假设我们有一个文件 test.txt,内容如下:

Hello world

This is a test file.

Welcome to the sed tutorial.

Linux is powerful.

Hello again.

test is important.

  1. 替换操作

将每行的第一个 "Hello" 替换为 "Hi"

sed 's/Hello/Hi/' test.txt

将所有的 "is" 替换为 "IS"(全局替换)

sed 's/is/IS/g' test.txt

将 "Hello" 替换为 "Hi",并且只打印发生替换的行

sed -n 's/Hello/Hi/p' test.txt

将第一个单词和最后一个单词互换(使用分组)

假设一行只有两个单词

sed -r 's/^([^ ]+) (.*)$/\2 \1/' test.txt

更通用的:交换第一个和最后一个字段(以空格分隔)

sed -r 's/^([^ ]+)(.* )([^ ]+)$/\3\2\1/' test.txt

在匹配到的内容前后添加字符(使用 &)

将 "Linux" 替换为 "[Linux]"

sed 's/Linux/[&]/g' test.txt

删除操作

删除第3行

sed '3d' test.txt

删除包含 "test" 的行

sed '/test/d' test.txt

删除从第2行到包含 "tutorial" 的行

sed '2,/tutorial/d' test.txt

删除所有空行

sed '/^$/d' test.txt

打印和其他操作

只打印第2到第4行

sed -n '2,4p' test.txt

打印包含 "is" 的行,并显示行号

sed -n '/is/{=;p}' test.txt

或者用分号分隔命令

sed -n '/is/=' test.txt # 只打印行号

sed -n '/is/p' test.txt # 只打印内容

在第2行之后插入一行 "--- INSERTED LINE ---"

sed '2a\--- INSERTED LINE ---' test.txt

在第1行之前插入一行 "--- START ---"

sed '1i\--- START ---' test.txt

文件操作

将包含 "Hello" 的行写入到新文件 hello.txt

sed -n '/Hello/w hello.txt' test.txt

在最后一行之后插入另一个文件 other.txt 的内容

sed '$r other.txt' test.txt

原地修改文件(-i 选项)

⚠️ 警告:此操作会直接修改原文件,务必小心!

直接修改文件,将所有 "is" 替换为 "IS"

sed -i 's/is/IS/g' test.txt

更安全的做法:先备份原文件(备份文件为 test.txt.bak)

sed -i.bak 's/is/IS/g' test.txt

综合案例

清理配置文件:删除所有注释和空行

假设注释以 # 开头

sed -e '/^#/d' -e '/^$/d' config.conf

或者

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

修改特定范围的行:将1到3行的 "Hello" 替换为 "Greetings"

sed '1,3s/Hello/Greetings/g' test.txt

使用脚本文件:将复杂的命令写在 script.sed 文件中

script.sed 内容:

s/Hello/Hi/g

/test/d

sed -f script.sed test.txt

总结

sed 的核心在于 s///(替换)、d(删除) 和 p(打印) 这三个命令,结合地址定界和正则表达式,可以完成绝大多数文本处理任务。

最佳实践:

在不使用 -i 选项时先测试命令,确认无误后再用 -i。

使用 -i.bak 创建备份是一个好习惯。

对于复杂的多步操作,使用 -e 连接多个命令或使用 -f 脚本文件

相关推荐
虎头金猫20 小时前
随时随地处理图片文档!Reubah 加cpolar的实用体验
linux·运维·人工智能·python·docker·开源·visual studio
NiKo_W20 小时前
Linux 数据链路层
linux·服务器·网络·内网穿透·nat·数据链路层
dessler20 小时前
MYSQL-物理备份(xtrabackup)使用指南
linux·数据库·mysql
郝学胜-神的一滴21 小时前
Effective Python 第52条:用subprocess模块优雅管理子进程
linux·服务器·开发语言·python
晨枫阳21 小时前
不同语言数组详解
linux·服务器·windows
q***75181 天前
Linux(CentOS)安装 MySQL
linux·mysql·centos
iru1 天前
kubectl cp详解,k8s集群与本地环境文件拷贝
运维·容器·k8s
CS_浮鱼1 天前
【Linux】线程
linux·c++·算法
q***13341 天前
Linux(CentOS)安装 Nginx
linux·nginx·centos
摘星编程1 天前
openGauss 快速上手:CentOS 环境下单机部署完整指南
linux·运维·centos