【shell】sed

一.sed

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

三.sed脚本格式

命令
p 打印当前模式空间内容,追加到默认输出之后
Ip 忽略大小写输出
d 删除模式空间匹配的行,并立即启用下一轮循环
a [\]text 在指定行后面追加文本,支持使用\n实现多行追加
i [\]text 在行前面插入文本
c [\]text 替换行为单行或多行文本
w file 保存模式匹配的行至指定文件
r file 读取指定文件的文本至模式空间中匹配到的行后
= 为模式空间中的行打印行号
! 模式空间中匹配行取反处理
q           结束或退出sed

格式:'地址+命令'组成
 不给地址:对全文进行处理(比如行号)

【shell】sed_第1张图片

单地址
单地址:
   #:指定的行,$:最后一行
  /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 	#显示第二行内容

【shell】sed_第2张图片

正则表达式
[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开头就全显示
重复循环

【shell】sed_第3张图片

步进
步进~
[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的行

【shell】sed_第4张图片

删除
删除
[root@localhost ~]seq 10 |sed '3d' #删除第三行
[root@localhost ~]seq 10|sed '2~3p' #删除以2开始步长为3的行
sed -n '/^#/d' fstab     #删除所有#号开头的行
sed -n '/^#/!p' fstab    #只显示非#开头的行

【shell】sed_第5张图片

修改文本
-i 用于修改文件内容,不加-i 修改后不回保存到文件中,一般修改前会备份文件

追加
[root@localhost ~]seq 5 |sed '2ahehe'		#第二行后追加hehe

插入
[root@localhost ~]seq 5 |sed '2ihehe'		#第二行前面插入hehe

替换
[root@localhost ~]seq 5 |sed '2chehe'		#第二行替换成hehe

【shell】sed_第6张图片

取反和显示行号
[root@localhost ~]seq 10 |sed -n '2!p' 	#取反
[root@localhost ~]sed '2=' /etc/passwd	#打印行号

【shell】sed_第7张图片

搜索替换
替换修饰符:
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

【shell】sed_第8张图片

[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

你可能感兴趣的:(linux,运维,服务器)