Linux sed
Stream EDitor,流式编辑器

  • 非交互,基于模式匹配过虑及批改文件
  • 逐行解决,并将后果输入到屏幕
  • 可实例对文本的输入、删除、替换、复制、剪切、导入、导出等各种操作

一、根本正则列表与扩大正则

依据推出工夫的不同,分为根本正则和扩大正则,扩大正则在根本正则的根底上做了一些优化和新增了一些正则表白符号,因为一些命令没有及时更新,所以你可能会遇到有些命令只反对根本正则,不反对扩大正则,或者须要增加一些反对扩大正则的选项。
对于正则与扩大正则区别的具体介绍能够看我另一篇shell 正则的介绍

根本正则列表

扩大正则列表

二、sed 文本处理工具的用法介绍:

  • 用法1:前置命令 | sed [选项]'条件指令'
  • 用法2:sed [选项]'条件指令' 文件....

相干阐明如下:

  • 条件能够是行号或者/正则/
  • 没有条件时,默认为所有条件
  • 指令能够是增、删、改、查等指令
  • 默认sed会将所有输入的内容都打印进去,能够应用-n屏蔽默认输入
  • 选项中能够应用-r选项,让sed反对扩大正则

sed命令的罕用选项如下:

  • -n 屏蔽默认输入,默认sed会输入读取文档的全部内容
  • -r 让sed反对扩大正则 若与其它选项一起应用,应放作为首选项
  • -i sed间接批改源文件,默认sed只是通过内存长期批改文件,源文件无影响
  • -e 多点编辑 让一条sed能够执行多条指令

sed命令罕用条件指令如下

  • d:删除指定的字符
  • p:显示指定的行
  • s:替换指定的字符
  • i: 在指定的行之前插入文本
  • a:在指定的行之后追加文本
  • c:替换指定的行
  • r:读取文件
  • w:保留到文件

三、意识sed工具的 n、r、i 选项指令

\# sed [选项] '条件指令' 文件.. ..
下面的条件指令 咱们能够拆分为 # sed [选项] '范畴界定+操作指令' 文件.. .. 的格局这样更容易了解

sed -n '/bash$/   s/:.*//p'  /etc/passwd  // 选项 -n 范畴界定/bash$/ + 操作指令s/:.*//p

sed命令能够应用行号或正则做为条件匹配:

1)sed命令的 -n 选项
执行p打印等过滤操作时,心愿看到的是符合条件的文本。但不应用任何选项时,默认会将原始文本一并输入,从而烦扰过滤成果。比方,尝试用sed输入/etc/hosts的第1行:

[root@server ~]# sed '1p'/etc/hosts127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

能够发现所有的行都被显示进去了(第1行反复2次)。—— 正确的用法应该增加 -n 选项,这样就能够只显示第1行了:

[root@server ~]# sed -n '1p'/etc/hosts127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

行号能够是间断的行号,如打印passwd第3到第6行账户的信息:

[root@server ~]# sed  -n '3,6p'/etc/passwdbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

2)sed命令的 -r 选项
须要用到扩大正则时,须要加 -r选项

[root@server ~]#  sed  -r 's/bash|nologin/xxxx/g'   '/etc/passwd      //把所有bash或nologin替换为xxxx

3)sed命令的 -i 选项
失常状况下,sed命令所做的解决只是把操作后果(包含打印、删除等)输入到以后终端屏幕,而并不会对原始文件做任何更改:

[root@server ~]# sed 'd'/etc/passwd                      //删除所有行[root@server ~]# cat /etc/passwd                          //查看原始文本,并未改变

若心愿间接批改文件内容,应增加选项 -i 。
须要特地留神的是,和一些指令组合和应用的先后顺序都会对最终输入后果产生影响
例如: 指令 -n、和操作操作p

[root@server ~]# sed -in 's/2017/xxx/' test.txt    // n在i前面不影响后果[root@server ~]# cat test.txtxxx20112018xxx20172024xxx20172017[root@server ~]# sed -ni 's/2017/xxx/' test.txt // n在i后面 因为n曾经屏蔽了所有显示 所以后果为空[root@server ~]# cat test.txt [root@server ~r]# sed -in 's/2018$/xxx/p' test.txt    // n在i前面不影响后果 但P前面的显示指令 让匹配项反复显示行写入到了文件[root@server ~]# cat test.txt20172011xxx20172011xxx201720172024201720172017[root@server ~]# sed -ni 's/2018$/xxx/p' test.txt  # n在i后面 前面 P指令只把匹配项写入了文件[root@server ~]# cat test.txt20172011xxx

比方,间接删除test.txt(自行创立一个任意内容的文件)的第1~4行:

[root@server ~]# sed -i '1,4d' test.txt            //删除操作[root@server ~]# cat test.txt                      //确认删除后果

下文中对于应用sed批改文件的示例中,为了防止大家在练习过程中因误操作导致系统故障,命令省略 –i 选项,不再逐个阐明。须要时,大家可自行加上此选项。
4)多个指令能够应用分号隔离
用分号来隔离多个操作,比方:

[root@server ~]# sed -n '1p;4p'/etc/passwdroot:x:0:0:root:/root:/bin/bashadm:x:3:4:adm:/var/adm:/sbin/nologin

1)行号案例

打印第3行:[root@server ~]# sed -n '3p'/etc/passwd打印第3到5行:[root@server ~]# sed -n '3,5p'/etc/passwd打印第3和5行:[root@server ~]# sed -n '3p;5p'/etc/passwd打印第3以及前面的10行:[root@server ~]# sed -n '3,+10p'/etc/passwd打印奇数行:[root@server ~]# sed -n '1~2p'/etc/passwd打印偶数行:[root@server ~]# sed -n '2~2p'/etc/passwd

2)正则案例

打印蕴含root的行:[root@server ~]# sed -n '/root/p'/etc/passwd打印bash结尾的行:[root@server ~]# sed -n '/bash$/p'/etc/passwd

3)没有条件,则示意匹配所有行

[root@server ~]# sed -n 'p'/etc/passwd

四、意识sed工具的 p、d、s 条件指令

1)上面看看sed工具的p指令案例集锦(本人提前生成一个a.txt文件)

[root@server ~]# sed  -n 'p' a.txt            //输入所有行,等同于cat a.txt[root@server ~]# sed  -n '4p' a.txt            //输入第4行[root@server ~]# sed  -n '4,7p' a.txt        //输入第4~7行[root@server ~]# sed  -n '4,+10p' a.txt        //输入第4行及其后的10行内容[root@server ~]# sed  -n '/^bin/p' a.txt        //输入以bin结尾的行[root@server ~]# sed  -n '$=' a.txt            //输入文件的行数

2)上面看看sed工具的d指令案例集锦(本人提前生成一个a.txt文件)

[root@server ~]# sed  '3,5d' a.txt             //删除第3~5行[root@server ~]# sed  '/xml/d' a.txt            //删除所有蕴含xml的行[root@server ~]# sed  '/xml/!d' a.txt         //删除不蕴含xml的行,**!符号示意取反**[root@server ~]# sed  '/^install/d' a.txt    //删除以install结尾的行[root@server ~]# sed  '$d' a.txt                //删除文件的最初一行[root@server ~]# sed  '/^$/d' a.txt             //删除所有空行

3)sed命令的s替换基本功能(s/旧内容/新内容/选项):

[root@svr5 ~]# vim  test.txt                //新建素材201720112018201720172024201720172017[root@server ~]# sed 's/2017/xxxx/'      test.txt   //将每行中第一个2017替换为xxxx[root@server ~]# sed 's/2017/xxxx/g'     test.txt  //将每行中所有2017替换为xxxx[root@server ~]# sed 's/2017/xxxx/2'     test.txt  //将每行中第2个2017替换为xxxx[root@server ~]# sed 's/2017//2'       test.txt      //将每行中第2个2017删除[root@server ~]# sed -n 's/2017/xxxx/p'     test.txt    //将每行中第一个2017替换为xxxx 并显示

4)上面看看sed工具的s指令案例集锦(本人提前生成一个a.txt文件)
留神:替换操作的分隔“/”可改用其余字符,如#、&等,便于批改文件门路

[root@server ~]# sed 's/xml/XML/'  a.txt        //将每行中第一个xml替换为XML[root@server ~]# sed 's/xml/XML/3' a.txt     //将每行中的第3个xml替换为XML[root@server ~]# sed 's/xml/XML/g' a.txt     //将所有的xml都替换为XML[root@server ~]# sed 's/xml//g'     a.txt     //将所有的xml都删除(替换为空串)[root@server ~]# sed 's#/bin/bash#/sbin/sh#' a.txt  //将/bin/bash替换为/sbin/sh[root@server ~]# sed '4,7s/^/#/'   a.txt         //将第4~7行正文掉(行首加#号)[root@server ~]# sed 's/^#an/an/'  a.txt         //解除以#an结尾的行的正文(去除行首的#号)

以下操作应用nssw.txt作为测试文件。
参考数据文件内容如下:

[root@server ~]# cat nssw.txtHello the worldni hao ma beijing

5)删除文件中每行的第二个、最初一个字符
分两次替换操作,第一次替换掉第2个字符,第二次替换掉最初一个字符:

[root@server ~]# sed 's/.//2 ; s/.$//' nssw.txt 

6)将文件中每行的第一个、倒数第1个字符调换
每行文本拆分为“第1个字符”、“两头的所有字符”、“倒数第1个字符”三个局部,而后通过替换操作重排程序为“3-2-1”:

[root@server~]# sed -r 's/^(.)(.*)(.)$/\3\2\1/' nssw.txt

7)删除文件中所有的数字
因原文件内没有数字,行首也没有空格,这里在内容中新增一些数字另外新几行内容 首行增加几行空格,生成一个新测试文件以 nssw2.txt

[root@server ~]# sed 's/[0-9]//' nssw.txt   //有效因为外面不蕴含数字

以nssw2.txt文件为例,删除所有数字、行首空格的操作如下:

[root@server ~]# sed -r 's/[0-9]//g;s/^( )+//' nssw2.txt

8)为文件中每个大写字母增加括号[]
应用“()”可实现保留性能,所以可参考下列操作解决:

[root@server ~]# sed -r 's/([A-Z])/[\1]/g' nssw.txt

五、意识sed工具的 i、a、c 条件指令

\# sed [选项] '条件指令' 文件..
sed工具的多行文本处理操作:

  • i: 在指定的行之前插入文本
  • a:在指定的行之后追加文本
  • c:替换指定的行

根本语法格局案例:

[root@server ~]# sed  '2a XX'   a.txt            //在第二行前面,追加XX[root@server ~]# sed  '2i XX'   a.txt            //在第二行后面,插入XX[root@server ~]# sed  '2c XX'   a.txt            //将第二行替换为XX

1)sed命令的 i 指定行之前插入基本功能

[root@server ~]# sed  '2i  xxxx'    nssw.txt   //将第二行前插入xxxx[root@server ~]# sed  'c  xxxx'    nssw.txt   //在所有行前插入xxxx

2)sed命令的a追加基本功能

[root@server ~]# sed  '3a  xxxx'    nssw.txt   //将第三行后追加xxxx[root@server ~]# sed  'a  xxxx'    nssw.txt   //在所有行后追加xxxx

3)sed命令的c替换基本功能

[root@server ~]# sed  '1c  xxxx'    nssw.txt   //将第一行替换为xxxx[root@server ~]# sed  'c  xxxx'    nssw.txt   //对所有行替换成xxx[root@server ~]# sed  '1,3c  xxxx'    nssw.txt   //对1到3行替换成xxx

六、意识sed高级利用 r、w 条件指令

新建文件 a.txt  n.txt[root@server sed]# cat a.txt aabbccddeeffgghhiijjkkll[root@server sed]# cat n.txt 112233445566778899001122

1)sed命令的 r 读取文件

[root@server sed]# sed '2r a.txt'  n.txt   \\在第2行插入a.txt1122334455667788aabbccddeeffgghhiijjkkll99001122[root@server sed]# sed '/^ee/r n.txt'  a.txt  \\在以ee结尾的行下方插入n.txtaabbccddeeffgghh112233445566778899001122iijjkkll[root@server sed]# sed '1,3r n.txt'  a.txt  \\在以1到3行下方别离插入n.txt

2)sed命令的 w 保留到文件

[root@server sed]# sed -n '1,3w c.txt' a.txt   \\把1到3主存储为新文件c.txt[root@server sed]# cat c.txt aabbccddeeffgghhiijjkkll[root@server sed]# sed -n '/^ii/w d.txt' a.txt  \\把ii结尾的行保留为d.txt[root@server sed]# cat d.txt iijjkkll

七、综合案例

1) 综合案例1

[root@server sed]# cp /etc/passwd .[root@server sed]# nl /etc/passwd | sed '2,5d'    // **删除2到5行 | 管道后应用 -i 选项有效**[root@server sed]# nl passwd | sed '3,$d'   //删除3到最初一行[root@server sed]# nl passwd | sed '2i hostfile' > passwd.new  //在第2行前插入''hostfile'' 并生成新文件 passwd.new[root@server sed]# nl passwd | sed -n '/root/p'  //显示蕴含root的行[root@server sed]# nl /etc/passwd | sed  '/root/{s/bash/black/;p;q}'  //花括号中的一组命令,每个命令之间用分号分隔,找到root的行把bash替换成clack  p输入显示 q是退出 [root@server sed]# ifconfig eth0 | grep 'inet'|sed 's/inet\s//g'|sed 's/\snetmask.*$//g'  \\获取本机的IP地址  其中\s 示意匹配空格[root@server sed]# sed -e '3,$d' -e 's/bash/blueshell/'  passwd  // 多点编辑 一条sed命令,删除/etc/passwd第三行到开端的数据,并把bash替换为blueshellroot:x:0:0:root:/root:/bin/blueshellbin:x:1:1:bin:/bin:/sbin/nologin

2)综合案例2 脚本利用

  • 本案例要求编写脚本getupwd.sh,实现以下需要:
    找到应用bash作登录Shell的本地用户
    列出这些用户的shadow明码记录
    按每行“用户名 --> 明码记录”保留到getupwd.log
  • 基本思路如下:
    先用sed工具取出登录Shell为/bin/bash的用户记录,保留为临时文件/tmp/urec.tmp,并计算记录数量
    再联合while循环遍历获得的账号记录,逐行进行解决
    针对每一行用户记录,采纳掐头去尾的形式取得用户名、明码字串
    依照指定格局追加到/tmp/getuupwd.log文件
    完结循环后删除临时文件,报告剖析后果
  • 脚本的编写
    步骤一:编写getupwd.sh脚本

    [root@server sed]# cat getupwd.sh #!/bin/bashA=$(sed -n '/bash$/ s/:.*//p' /etc/passwd)     ##提取符合条件的帐号记录for i in $A              ##遍历帐号记录do  pass1=$(grep $i /etc/shadow)  ##搜寻对应帐号shadow中的行  pass2=${pass1#*:}     pass=${pass2%%:*}          ##截取明码  echo "$i -->$pass"done[root@server sed]# ./getupwd.sh root -->$6$SAyc777Q$DgGi7Pnln0or.Ds04oyL6Y.QnVlMgZDRHMKKICJhiUAHBy4lvziPAZoW0MJz81xYonskLozvzhvNa4H59ngSl1nginx -->!!bigyong -->!!kaka5 -->$6$uyZDpbUl$.CjkBefPZHXrRTcKc1csv7ZbbhHMMD4oQmum9lajJ1ot9at6fmIey5AE4kmUSoaWE/ofmFxyP2Dc6PAcczXdw0harry -->!!