linux下sed的使用+练习

sed是款非交互式的编辑器,它没有破坏性,不会修改文件,除非使用重定向来保存输出结果,默认
情况下,所有的输出行都被打印在屏幕上。
sed把当前正在处理的行保存在一个临时缓冲区中,这个缓冲区被称为模式空间或临时缓冲。sed处理
完模式空间中的行后,就把该行发送到屏幕上。每处理完一行就将其从模式空间中删除,然后将下一
行读入空间,进行处理和显示。 sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会
修改或破坏原文件。
下面是sed的命令和选项。
a\                        在当前行后添加一行或多行
c\                         用新文本修改(替换)当前行中的文本
d                          删除行
i\                          在当前行之前插入文本
h                          把模式空间里的内容复制到暂存缓冲区
H                          把模式空间里的内容追加到暂存缓冲区
g                           取出暂存缓冲区的内容,将其复制到模式空间,覆盖该处原有内容
G                          取出暂存缓冲区的内容,将其复制到模式空间,追加到原有内容后面
l                            列出非打印字符
p                           打印行
n                           读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理
q                           结束或退出sed
r                            从文件中读取输入行
!                            从所选行以外的所有行应用命令
s                            用一个字符串替换另一个
替换标志
g                            在行内进行全局替换
p                            打印行
w                            将行写入文件
x                             交换暂存缓冲区与模式空间的内容
y                             将字符转换为另一字符

选项
-e                            允许多项编辑
-f                             指定sed脚本文件名
-n                            取消默认的输出
如果需要使用多条命令,或需要在某个地址范围内嵌套地址,就必须用花括号将命令括起来,每行
只写一条命令,或用分号分隔同一行中的多条命令。

紧跟在s命令后的字符就是查找串和替换串之间的分隔符。分隔符默认为正斜杠,但可以改变。无论
什么字符(换行符,反斜线除外),只要紧跟s命令,就成了新的串分隔符。这个方法在查找包含正
斜杠的模式时很管用,例如查找路径名或生日。

sed支持的元字符
^                               行首定位符                 /^love/                   匹配所有love开头的行
$                              行尾定位符                 /love$/                  匹配所有以love结尾的行
.                               匹配除换行符
                                之外的单个字符          /l..e/                      匹配包含l,后跟两个任意字符,再
                                                                                                跟字母e的行
*                              匹配0或多个前字符     /*love/                 匹配在0或多空格紧跟着模式love的行
[]                             匹配指定字符组内的                            
                               任一字符                     [lL]ove/                匹配包含love和Love的行
[^]                            匹配不再指定字符组
                               内的任一字符             /[^A-KM-Z]ove/      匹配包含ove但之前的字符不在A至K或
                                                                                              M至Z之间的行
\(..\)                         保存已匹配的字符     s/\(love\)able/\1er/      loveable被替换为lover
&                            保存查找串以便在
                               替换串中引用             s/love/**&**/             love变成了**love**
\<                            词首定位符                 /\<love/                   匹配包含以love开头的单词的行
\>                            词尾定位符                 /love\>/                   匹配包含以love结尾的单词的行
x\{m\}                      连续m个x                    /o\{5\}/
x\{m,\}                     至少m个x                    /o\{5,\}/
x\{m,n\}                   至少m个,但不超过n个    /o\{5,10\}/


练习回顾
sed -n '/sentimental/p' filex                    把文件filex中所有包含sentimental的行打印在屏幕上
                                                              filex的内容不会被改变 如果没有-n选项,所有包含
                                                              sentimental的行都会被打印两次
sed '1,3d' filex > newfilex                       删除文件filex的前3行,将修改的结果保存在newfilex文件中
sed '/[Dd]aniel/d' filex                            删除包含Daniel或daniel的行
sed -n '15,20p' filex                               只打印第15~20行
sed '1,10s/Montana/MT/g' filex              将1~10行所有Montana全局替换为MT(如果没有g替换选项
                                                                 将只替换每行中的第一个Montana)
sed '/March/!d' filex(sh)
sed '/March/\!d' filex(csh)                       删除所有不含March的行(只在csh中才要用反斜杠转义)
sed '/report/s/5/8' filex                            把所有包含report的行里出现的第一个5改为8
sed 's/...$//' filex                                     删除每行的后3个字符
sed 's/...//' filex                                       删除每行的前3个字符
sed '/east/,/west/s/North/South/' filex     把从east到west这个范围内所有行出现的North替换为South
sed -n '/Time off/w timefile' filex              将所有包含Time off的行写入到timefile文件中
sed 's/\([Oo]ccur\)ence/\1rence/' file      将所有Occurence替换成Occurence,occurence替换成occurence
sed -n '|' filex                                           打印所有以\nn显示非打印字符,制表键(tab)显示为>的行

[root@linux ~]# sed [-nefr] [动作]

练习

范例一∶将 /etc/passwd 的内容列出,并且我需要列印行号,同时,请将第 2~5 行删除!
[root@linux ~]# nl /etc/passwd | sed '2,5d'
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
.....(后面省略).....
# 看到了吧?因为 2-5 行给他删除了,所以显示的资料中,就没有 2-5 行棉~
# 另外,注意一下,原本应该是要下达 sed -e 才对,没有 -e 也行啦!
# 同时也要注意的是, sed 后面接的动作,请务必以 '' 两个单引号括住喔!
# 而,如果只要删除第 2 行,可以使用 nl /etc/passwd | sed '2d' 来达成,
# 至于第 3 到最后一行,则是 nl /etc/passwd | sed '3,$d' 的啦!

范例二∶承上题,在第二行后(亦即是加在第三行)加上『drink tea?』字样!
[root@linux ~]# nl /etc/passwd | sed '2a drink tea'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
drink tea
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
# 嘿嘿!在 a 后面加上的字串就已将出现在第二行后面棉!那如果是要在第二行前呢?
# nl /etc/passwd | sed '2i drink tea' 就对啦!

范例三∶在第二行后面加入两行字,例如『Drink tea or .....』『drink beer?』
[root@linux ~]# nl /etc/passwd | sed '2a Drink tea or ....../
> drink beer ?'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
Drink tea or ......
drink beer ?
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
# 这个范例的重点是,我们可以新增不只一行喔!可以新增好几行~
# 但是每一行之间都必须要以反斜线 / 来进行新行的增加喔!所以,上面的例子中,
# 我们可以发现在第一行的最后面就有 / 存在啦!那是一定要的喔!

范例四∶我想将第2-5行的内容取代成为『No 2-5 number』呢?
[root@linux ~]# nl /etc/passwd | sed '2,5c No 2-5 number'
1 root:x:0:0:root:/root:/bin/bash
No 2-5 number
6 sync:x:5:0:sync:/sbin:/bin/sync
# 没有了 2-5 行,嘿嘿嘿嘿!我们要的资料就出现啦!

范例五∶仅列出第 5-7 行
[root@linux ~]# nl /etc/passwd | sed -n '5,7p'
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
# 为什么要加 -n 的参数呢?您可以自行下达 sed '5,7p' 就知道了!(5-7行会重复输出)
# 有没有加上 -n 的参数时,输出的资料可是差很多的喔!

范例六∶我们可以使用 ifconfig 来列出 IP ,若仅要 eth0 的 IP 时?
[root@linux ~]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:51:FD:52:9A:CA
inet addr:192.168.1.12 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::250:fcff:fe22:9acb/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
.....(以下省略).....
# 其实,我们要的只是那个 inet addr:..那一行而已,所以棉,利用 grep 与 sed 来捉
[root@linux ~]# ifconfig eth0 | grep 'inet '|sed 's/^.*addr://g'|sed 's/Bcast.*$//g'
[root@linux ~]# ifconfig eth0 | grep 'inet '|sed 's/^.*addr://g'|sed 's/ Bcast.*$//g'
#这两行命令差不多,但是第二行在Bacst前有个空格,一定要注意,说明连空格在内都去除了,可以使用
#上面两行命令重向到两个文本文件中,例如1.txt 2.txt 仔细查看这两个文件的大小
# 您可以将每个管线 (|) 的过程都分开来执行,就会晓得原因棉!
# 去头去尾之后,就会得到我们所需要的 IP 亦即是 192.168.1.12 棉~

范例七∶将 /etc/man.config 档案的内容中,有 MAN 的设定就取出来,但不要说明内容。
[root@linux ~]# cat /etc/man.config | grep 'MAN'| sed 's/#.*$//g'| sed '/^$/d'
# 每一行当中,若有 # 表示该行为注解,但是要注意的是,有时候,
# 注解并不是写在第一个字元,亦即是写在某个指令后方,如底下的模样∶
# 『shutdown -h now # 这个是关机的指令』,注解 # 就在指令的后方了。
# 因此,我们才会使用到将 #.*$ 这个正规表示法!

范例八∶利用 sed 直接在 ~/.bashrc 最后一行加入『# This is a test』
[root@linux ~]# sed -i '$a # This is a test' ~/.bashrc
# 上头的 -i 参数可以让你的 sed 直接去修改后面接的档案内容喔!而不是由萤幕输出。
# 至于那个 $a 则代表最后一行才新增的意思。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值