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 脚本文件

相关推荐
用户97183563346617 小时前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪18 小时前
linux 拷贝文件或目录到指定的位置
linux
大树881 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠1 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质1 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush41 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5201 天前
Linux 11 动态监控指令top
linux
小宇宙Zz1 天前
Maven依赖冲突
java·服务器·maven
Inhand陈工1 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智2 天前
ARP代理--工作原理
运维·网络·arp·arp代理