Sed是从文件或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行,直到最后一行。每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间(PatternSpace),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。一次处理一行的设计模式使得sed性能很高,sed在读取大文件时不会出现卡顿的现象。如果使用vi命令打开几十M上百M的文件,明显会出现有卡顿的现象,这是因为vi命令打开文件是一次性将文件加载到内存,然后再打开。Sed就避免了这种情况,一行一行的处理,打开速度非常快,执行速度也很快
语法:sed [命令选项] ‘匹配地址 脚本命令’ 文件名或标准输出或标准输入
常用的命令选项:
选项 | 功能 |
---|---|
-n | 不输出模式空间的内容到屏幕,不自动打印 |
-e | 多点编辑器,相当于/匹配1|匹配2/ |
-f filenamed |
从指定文件中读取编辑脚本 |
-r,-E | 使用扩展正则表达式 |
-i.bak | 备份文件并原处编辑 |
-ir不支持 -i -r支持 -ri 支持 -ni 会清空文件 |
sed [选项] '自身脚本用法' [支持输入标准输入管道]
常用选项:
-n 不输出模式空间内容到屏幕,即不自动打印
-e 多点编辑
-f FILE 从指定文件中读取编辑脚本
-r, -E 使用扩展正则表达式
-i.bak 备份文件并原处编辑
-s 将多个文件视为独立文件,而不是单个连续的长文件流
sed -i 作为行编辑器,一旦生效无法撤回,所以建议修改的时候加上-i.bak 进行备份
[root@localhost data]#sed -i.bak '1,4d' html.txt
[root@localhost data]#cat html.txt
http://www.google.com/index.html
http://www.yahoo.com.cn/put.html
[root@localhost data]#ls
123.txt html.txt html.txt.bak md5.txt sort.sh uniq.sh
[root@localhost data]#cat html.txt.bak
##bak也可以是别的字母,只是因为bak是backup的缩写,所以常使用bak
命令
p 打印当前模式空间内容,追加到默认输出之后
Ip 忽略大小写输出
d 删除模式空间匹配的行,并立即启用下一轮循环
a [\]text 在指定行后面追加文本,支持使用\n实现多行追加
i [\]text 在行前面插入文本
c [\]text 替换行为单行或多行文本
w file 保存模式匹配的行至指定文件
r file 读取指定文件的文本至模式空间中匹配到的行后
= 为模式空间中的行打印行号
! 模式空间中匹配行取反处理
q 结束或退出sed
格式:'地址+命令'组成
不给地址:对全文进行处理(比如行号)
单地址:
#:指定的行,$:最后一行
/pattern/:被此处模式所能够匹配到的每一行,正则表达式
[root@localhost ~]seq 5 |sed 'p' #带有自动打印功能,p又打印一遍
[root@localhost ~] seq 5 | sed -n 'p' #-n关闭打印功能
[root@localhost ~]seq 5 | sed -n '3p' #显示第三行的内容
[root@localhost ~]seq 5 | sed -n 2p #显示第二行内容
正则表达式
[root@localhost ~]sed -n '/root/p' /etc/passwd #将包含root的行打印出来
地址范围
#,# #从#行到第#行,3,6 从第3行到第6行
#,+# #从#行到+#行,3,+4 表示从3行到第7行
/pat1/,/pat2/ 第一个正则表达式和第二个正则表达式之间的行
#,/pat/ 从#号行为开始找到 pat为止
/pat/,# 找到#号个pat为止
[root@localhost ~]seq 10|sed -n '3,6p'#显示第三行到第六行
[root@localhost ~]seq 10| sed -n '3,+4p' #显示第三行和第三行的后四行
[root@localhost ~]sed -n '/^b/,/^f/p' /etc/passwd #显示以b开头和以f开头的中间行
先开始找b开头一直找到f开头
然后再重新找b开头,一找到f开头,没有f开头就全显示
重复循环
步进~
[root@localhost ~]seq 10|sed -n '1~2p' #打印奇数行
[root@localhost ~]seq 10|sed -n '2~2p' #打印偶数行
[root@localhost ~]seq 10|sed -n '3~2p' #打印以三开始步长为2的行
删除
[root@localhost ~]seq 10 |sed '3d' #删除第三行
[root@localhost ~]seq 10|sed '2~3p' #删除以2开始步长为3的行
sed -n '/^#/d' fstab #删除所有#号开头的行
sed -n '/^#/!p' fstab #只显示非#开头的行
-i 用于修改文件内容,不加-i 修改后不回保存到文件中,一般修改前会备份文件
追加
[root@localhost ~]seq 5 |sed '2ahehe' #第二行后追加hehe
插入
[root@localhost ~]seq 5 |sed '2ihehe' #第二行前面插入hehe
替换
[root@localhost ~]seq 5 |sed '2chehe' #第二行替换成hehe
[root@localhost ~]seq 10 |sed -n '2!p' #取反
[root@localhost ~]sed '2=' /etc/passwd #打印行号
替换修饰符:
g 行内全局替换
p 显示替换成功的行
w /PATH/FILE 将替换成功的行保存至文件中
I,i 忽略大小写
s/旧字符/新字符/修饰符 查找替换,支持使用其它分符,可以是其它形式:s@@@,s###
[root@localhost ~]sed 's/root/admin/g' /etc/passwd
[root@localhost ~]sed 's/root/&er/g' /etc/passwd #&指代之前的内容
分组
s//代表查找替换 ()代表分组 \1 代表留下的组
[root@localhost ~]echo 123abcxyz |sed -r 's/(123)(abc)(xyz)/\1/'
[root@localhost ~]echo 123xyzabc |sed -r 's/(123)(xyz)(abc)/\1\3/'
[root@localhost ~]ifconfig ens33|sed -rn '2s/.*inet ([0-9.]+) .*/\1/p'
192.168.91.100
[root@localhost ~]cat a.txt
root
riit
roit
[root@localhost ~]#sed 's/root/&er/g' a.txt
#&指代之前找到的内容
[root@localhost ~]cat a.txt
rooter
riiter
roiter
[root@www data]name=root #定义变量
[root@www data]sed -nr '/$name/p' /etc/passwd
[root@www data]sed -nr "/$name/p" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@www data]sed -nr '/'$name'/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@www data]port=8080
[root@www data]sed -ri 's/^Listen 80/Listen '$port'/' httpd.conf