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/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
127.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/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
行号能够是间断的行号,如打印 passwd 第 3 到第 6 行账户的信息:
[root@server ~]# sed -n '3,6p'/etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp: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.txt
xxx20112018
xxx20172024
xxx20172017
[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.txt
20172011xxx
20172011xxx
201720172024
201720172017
[root@server ~]# sed -ni 's/2018$/xxx/p' test.txt # n 在 i 后面 前面 P 指令只把匹配项写入了文件
[root@server ~]# cat test.txt
20172011xxx
比方,间接删除 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/passwd
root:x:0:0:root:/root:/bin/bash
adm: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 // 新建素材
201720112018
201720172024
201720172017
[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.txt
Hello the world
ni 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
aabbccdd
eeffgghh
iijjkkll
[root@server sed]# cat n.txt
11223344
55667788
99001122
1)sed 命令的 r 读取文件
[root@server sed]# sed '2r a.txt' n.txt \\ 在第 2 行插入 a.txt
11223344
55667788
aabbccdd
eeffgghh
iijjkkll
99001122
[root@server sed]# sed '/^ee/r n.txt' a.txt \\ 在以 ee 结尾的行下方插入 n.txt
aabbccdd
eeffgghh
11223344
55667788
99001122
iijjkkll
[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
aabbccdd
eeffgghh
iijjkkll
[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 替换为 blueshell
root:x:0:0:root:/root:/bin/blueshell
bin: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/bash A=$(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.QnVlMgZDRHMKKICJhiUAHBy4lvziPAZoW0MJz81xYonskLozvzhvNa4H59ngSl1 nginx -->!! bigyong -->!! kaka5 -->$6$uyZDpbUl$.CjkBefPZHXrRTcKc1csv7ZbbhHMMD4oQmum9lajJ1ot9at6fmIey5AE4kmUSoaWE/ofmFxyP2Dc6PAcczXdw0 harry -->!!