Linux sed命令解析

sed是一种流线型、非交互式编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非使用重定向存储输出。sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
sed中动作都是使用单引号(’ ')括起来的。

选项与参数:

  • -n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
  • -e :直接在命令列模式上进行 sed 的动作编辑;
  • -f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
  • -r :sed 的动作支持的是延伸型正则表达式。(默认是基础正则表示法语法)
  • -i :直接修改读取的文件内容,而不是输出到终端,文件内容会改变。

常用命令:

  • p : 打印,将某个选择的数据打印出来。通常会与参数sed -n 一起使用
  • d : 删除,不用跟任何参数
  • s : 替换,通常这个s的动作可以搭配正规表示法。
  • w:将替换成功的行写入指定文件中

p :打印动作分析

不加参数直接使用p命令打印:

[root@admin home]# sed 'p' 12.txt
asdfsd
asdfsd
cccdgg
cccdgg
#直接使用一个p,将内容打印了2遍

[root@admin home]# sed '1p' 12.txt
asdfsd
asdfsd
cccdgg

使用1p时,只是把第一行打印了2遍
这些都是sed的特性,将所有来自 STDIN 的数据都被列出到终端上。然后又加了一个数字1,那第一行又被打印了一次。

加上-n参数后,指定哪行打印哪行:

[root@admin home]# sed -n '1p' 12.txt  
asdfsd

这样的效率是最高的,对整个文件只遍历一次

sed通常情况下会通过管道的形式来完成它的任务。

打印第2行到第4行,包括边界行:

[root@admin home]# cat -n 11.txt | sed -n '2,4p'
     2	
     3	bbbb
     4	this is aaccdd	
     

cat -n 表示列出行号,如这的 2 3 4。
这个效率要差一些,因为cat就已经将文件遍历一次,然后通过管道的形式传给sed,sed再去打印出来。
也可以使用下面的命令实现这个打印

[root@admin home]# cat -n 11.txt | head -4 | tail -3

这种效率是最低的,先通过cat遍历一遍整个文件,然后通过管道传给head,head再取出前4行,然后再通过管道传给tail,tail再打印出后3行。明显多出了几步,这个文件的行数少,到时没多大影响,但要是文件内容多了,效率就很低了。

sed中的匹配,使用 /…/ 实现

#匹配文件中连续的bb的内容,这个动作跟grep很像
[root@admin home]# cat 11.txt | sed -n '/bbb*/p'
bbbb
ccccbbbcccdddfgg

sed中加入正则表达式

#打印出文件中所有的空行,sed可以包括换行符\n,制表符\t,空格等形成的空行。
[ \t]就代表空行。
[root@admin home]# cat 11.txt | sed -n '/^[ \t]*$/p'

#打印文件中以this单词开头的行
[root@admin home]# cat 11.txt | sed -n '/^this/p'
this is aaccdd

扩展正则表达式:
[root@admin tody]# sed -r 's/ab+/!/' a.txt 
this is a test
a
aa
!
!
!c

对于扩展的正则表达式字符,比如 +、?、| ,前面必须加 -r 参数。
基础的是 . 、 * 、 ^ 、 $等。

打印文件中两个以this开头行及其之间的行

[root@admin home]# cat 11.txt | sed -n '/this/,/this/p'
this is aaccdd	
				
ccccbbbcccdddfggi

this is space
#及两次匹配this,中间用逗号隔开

但是这种匹配会引出一个问题,当我文件内容中有3个或者3个以上的行都是以this开头的,它又会怎么打印呢?实例如下:

实例1:

#匹配打印this及其之间的行
[root@admin home]# cat 11.txt
aaaaa
bbbb
this is aaccdd					
ccccbbbcccdddfggi
this is space
sdfggccdd
this this 
dsdf
[root@admin home]# cat 11.txt | sed -n '/this/,/this/p'
this is aaccdd					
ccccbbbcccdddfggi
this is space
this this 
dsdf

实例2:

#匹配打印连续字母a和连续字母b及其之间的行
[root@admin home]# cat 12.txt
asdfad
aaaaaddfd
sdfsdfghghdf
bbbbbhjjh
this is aaaa
asdfa
bbbb
gewrwe
[root@admin home]# cat 12.txt | sed '/aaa*/,/bbb*/p'
asdfad
gewrwe

实例3:

#匹配打印字母a和字母b及其之间的行
[root@admin home]# cat 14.txt
a
b
b
a
b
c
d
e
f
[root@admin home]# cat 14.txt | sed  '/a/,/b/d'
b
c
d
e
f

上面几个实例中,怎么好像有的实例的运行结果并不是我们预想的呢?为什么会出现这样的结果呢?
其实这里有三种情况,我把它浓缩成两种情况来说明一下出现这样结果的原因:

第一种情况,是命令中第一个需要匹配的字符或者是字符串在文中出现的位置,在与第二个需要匹配的字符或字符串成对匹配的过程中,位置始终在第二个需要匹配的字符或字符串位置的前面,如上面实例2中连续的a与连续的b在成对匹配,连续的a的位置始终在连续b的前面,这样的文件内容在匹配时出现上面情况的原因如下:

其实原因很简单,就是编写人设计的算法原理的问题。sed工具就是一次处理一行的内容,当找到第一次出现this的行以后,它会对这个行做个标记,比如为1。然后继续寻找第二次出现this的行,标记为2(注意:无论这行中有多少个this,都算在一行来处理),然后将这几行的内容打印出来。但是这个文件内容还没扫描完,它会继续往下扫描,继续寻找第三次出

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值