入门一班 20181017 sed

10月17日任务

10月17日任务
9.4/9.5 sed



sed -n '/关键字/'p 文件名


sed -n ‘数字’p 文件名  就是打印第数字行的那一行内容

注意以上的区别,有/ /的是关键字  不带/ / 的是行号


有一个例题:

例如:有个文件test的内容如下:
ert
fff
**
[abcfd]
123
324
444
[rty]
**
fgfgf
怎么能截取
[abcfd]
123
324
444
[rty]
这一部分出来呢?

答案: sed -n '/\[abcfd\]/,/\[rty\]/p' test

解析: 首先判断是两个关键字,所以基本的形式应该是 sed -n '/关键字1/,/关键字2/'p filename

扫描二维码关注公众号,回复: 3603329 查看本文章

因为是[]这种符号所以要加上脱义 \ 所以就 sed -n '/\[abcfd\]/,/\[rty\]/p' test

所以如果不是[]就不需要\来脱义了

image.png

image.png

支持 . * +(脱义),如果不想脱义的话,可以使用-r选项 

image.png

其他的也都是可以匹配的,只是稍微麻烦。


如果想用sed打印指定的行

sed -n '2'p passwd

打印第二行

image.png

sed -n '2,5'p passwd

打印2-5行


sed -n '2,$'p passwd 

打印第二行到最后一行

image.png

sed -n '1,$'p passwd

打印全部的行

image.png



-e表示可以同时执行多条匹配


sed -e '1'p  -e '/root/'p -e '/oo*/'p passwd 

相当于把三个条件满足的都打印出来



另外sed也可以大小写全部打印出来,在p前面加上一个I 大写的I

sed -n  '/bus/'Ip passwd

image.png


sed还有一个作用是显示剩余的行,sed '要删除的行'd filename

sed '1,10'd test,txt

的意思就是打印删除10行后剩余的内容

当然也可以按照关键字所在的行删除显示剩余的。 比如查看非root所在行。可以 sed '/root/'d passwd

image.png

image.png

sed 有一个真正删除的选项 -i  真的会把内容进行更改

sed -i‘行'd filename

image.png

除了按照行号来删以外还可以按照关键字所在的行来删。

sed -i '/zt/'d passwd 是将含有root的那一行删掉

image.png


当然sed最重要的功能是查找替换

sed '1,10s/home/lovebay/g' passwd1

       1-10行  home换成 lovebay g代表全局 

image.png


sed替换也支持正则。

sed  -r '1,5/lov+/my/g' passwd1 记住要有一个选项 -r

image.png


下面这个替换是将第一位和最后以为进行了互换位置

sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:\1/'  [^:]非:开头  (.*):一直匹配到最后一个:的位置 最后也是一个非:开头 然后后面跟的是位置 


基本的做法是将第一个冒号前面 中间 最后一个冒号后面 分成了三部分 然后再将这三部分放到3 2 1的位置上 进行了互换

image.png


如果有/的时候要脱义 \ 或者有其他的符号作为分割符比如@#

head passwd1 |sed 's/\/bin\/bash/123/g'

head passwd1 |sed 's@\/bin\/bash@123@g'

image.png


如果是想把所有的英文字母删掉

head passwd1 | sed 's/[a-zA-Z]//g' 这个比较好理解,删除掉就是替换成空就可以了

image.png


如果想在每一行前面加上aaa如何办?

两个办法,第一个办法是\1这个位置符前面加东西

head passwd1 | sed -r 's/(.*)/aaa:\1/'

image.png

或者是用&表示前面括号里的内容

image.png

image.png


关于转义的扩展

在sed命令中有许多的字符都被转义,比如\ , $, ^,单双引号还有点号等等,因此使用sed命令进行字符串的匹配和修改的时候,字符串中如果含有转义字符,很多情况下不能直接用字符本身表示。这时候可以使用反斜杠加上转义字符的方法来输出含转义字符的字符串,但这一方法并不是对所有的转义字符都有用,过程也较复杂。下面一一说明:

一般而言sed命令格式由三部分组成,sed + 功能选项 + 条件选项,功能选项由连接符号-加上代表不同功能的字母构成,条件选项表明对文本的筛选和处理条件,一般括在单引号或者双引号中。但两种引号在sed命令处理的过程中略有不同:
单引号:对其中的内容不做任何处理,即引号内的内容是sed命令定义的格式,对于在条件选项中使用的转义字符需要使用反斜杠加转义字符才能输出。例如:
若定义变量 temp=/home/test/, var=aa
>echo $temp | sed 's/\//$var/g'
输出结果为:$varhome$vartest$var
你可能会发现并不是所有的转义字符都需要加反斜杠来输入(如上例中的$符号),这取决于转义字符在条件选项中的位置,如果在这个位置字符本身转义起作用,则需要加反斜杠。即sed命令先检查字符转义功能是否成立,若有转义功能则使用转义功能,否则按字符输出。如果你想要输出该字符时不确定该字符是否会转义,可以对所有位置添加反斜杠。

双引号:会对其中的变量进行直接转换,同样是上例,如果写成:
>echo $temp | sed “s/\//$var/g”
则输出结果为:aahomeaatestaa
可以看出双引号将变量名直接替换成变量内容。

要想使用单引号得到上面双引号的输出结果也是可以做到的,这时候需要对变量名加单引号来处理:
>echo $temp | sed 's/\//'$var'/g'
同样可以得到输出结果为:aahomeaatestaa

对于sed命令,如上例单引号命令>echo $temp | sed 's/\//$var/g' 中,我们对斜杠符号的输出加上了反斜杠,以免被sed命令视为转义字符功能。我们还可以采用另一种方法无需使用加反斜杠来输出斜杠字符。在这个命令中,分隔符使用了斜杠(/),因此斜杠默认转义,sed中是可以使用其他符号作为分符的,如果不使用斜杠作为分隔符,则斜杠默认无转义功能,时就不需要借助反斜杠来输出了:
>echo $temp | sed 's#/#'$var'#g'
这里我们使用#来代替/当分隔符,因此/不再具有转义功能,无需再加反斜杠来辨识。同样可以得到上面的输出效果。分隔符对单引号和双引号作用一样。

若字符串中含有单引号,有的时候会发现加反斜杠还是得不到想要的字符串输出。比较简单的一个做法是字符串中有单引号时,功能选项部分用双引号括起来,这样不用加反斜杠可以直接输出字符。例如:
>echo $temp | sed "s#/#'#g"
输出结果为:'home'test'
同理上例如果写成:>echo $temp | sed 's#/#\'#g'
则会报错。因为引号需要成对出现,否则sed命令无法知道第一个引号究竟与第二个还是第三个引号匹配。

若字符串中含有双引号时,功能选项部分用单引号括起来,也可以不使用反斜杠来输出双引号。
>echo $temp | sed 's#/#"#g'
输出结果为:"home"test"
但是,与单引号不同的是,上例如果写成:>echo $temp | sed "s#/#\"#g",却不会报错。这也就很好的解决了如果字符串中同时有单双引号的时候该如何处理的问题。




扩展:大小写转换

sed中,使用\u表示大写,\l表示小写

1. 把每个单词的第一个小写字母变大写:
sed 's/\b[a-z]/\u&/g' filename

2. 把所有小写变大写:
sed 's/[a-z]/\u&/g' filename

3. 大写变小写:
sed 's/[A-Z]/\l&/g' filename


\b代表边界符 & 表示 第一个 /  / 里面的内容





如何使用sed打印1到100行包含某个字符串的行

这个需求,其实就是sed指定行范围匹配,较少见。实现:

sed  -n '1,100{/abc/p}'  1.txt


sed删除某关键字的下一行到最后一行

回复收藏



[root@test200 ~]# cat test
a
b
c
d
e
f
[root@test200 ~]# sed '/c/{p;:a;N;$!ba;d}' test
a
b
c

定义一个标签a,匹配c,然后N把下一行加到模式空间里,匹配最后一行时,才退出标签循环,然后命令d,把这个模式空间里的内容全部清除。

if 匹配"c"
:a
追加下一行
if 不匹配"$"
goto a
最后退出循环,d命令删除。


猜你喜欢

转载自blog.51cto.com/13691454/2301446