什么是正则表达式?
- 使用"一串符号"来描述有共同属性的数据
- 使用某些符号结合相关工具对文本进行筛选,过滤,查找
正则符号 | 含义 |
^ | 匹配行首 |
$ | 匹配行尾 |
[ ] | 集合,匹配集合中任意单个字符 |
[x-y] | 匹配连续的字符串范围 |
[^] | 对集合取反 |
. | 匹配任意单个字符(空格) |
* | 匹配前一个字符任意次数(0次) [*不允许单独使用](空格,空行) |
.* |
匹配多个任意字符 |
\ | 匹配转义后的字符串 |
\n | 通过\1至\9调用保留空间中的内容 |
\{n,m\} | 匹配前一个字符n到m次 |
\{n\} | 匹配前一个字符n次 |
\{n,\} | 配前一个字符n次及以上 |
\( \ ) | 保留,有复制功能 |
egrep过滤工具
文本处理顺序
- 以行为单位,逐行进行处理
- 默认只输出与表达式相关匹配的文本行
基本用法:
- 格式1: egrep [选项] '正则表达式' 文件...
- 格式2: 前置命令 | egrep [选项] '正则表达式'
常用命令选项:
- -i : 忽略字母大小写
- -v : 条件取反
- -c : 统计匹配的行数
- -q : 静默,无任何输出,一般用于检测 ---------看$?返回值,0为匹配,非0则无匹配
- -n : 显示匹配结果所在的行号
- --color : 标红显示匹配字串
grep过滤工具
- 根据字串符模式提取文本
- 支持正则表达式
- 匹配模式最好加上双引号""
基本用法:
- 格式: grep [选项] '匹配模式' 文本文件...
常用命令选项:
- -i : 忽略大小写
- -v : 取反匹配
- -n : 显示行号
- -q : 静默不输出
- -E : 支持扩展正则
- -o : 仅显示匹配内容,不显示全行所有内容
- -w : 显示匹配内容,显示全行所有内容
[root@proxy mnt]# head -5 /etc/passwd > /mnt/test ##以test为素材
[root@proxy mnt]# cat test
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# grep root test ##查找有root的行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep ^root test ##查找以root开头的行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep bash$ test ##查找以bash结尾的行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep "[ro]" test ##查找字母r或者o的行
root:x:0:0:root:/root:/bin/bash
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
[ ] 范围内单字匹配
- 匹配指定字符集合内的任何一个字符
- [ ] 内加^可取反
示例 | 说明 |
[alc45_?] | 匹配 a l c 4 5 _ ? |
[a-z] | 匹配任意小写字母 |
[A-Z] | 匹配任意大写字母 |
[0-9] | 匹配任意数字 |
[a-Z0-9] | 匹配任意字母或数字 |
[^A-Z ] | 匹配包含非大写字母的行 |
^[^a-z] | 匹配不以小写字母开头的行 |
[root@proxy mnt]# grep "[a-z]" test ##查找所有小写字母
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# grep "[A-Z]" test ##查找所有大写字母 素材内无大写所以无匹配.
[root@proxy mnt]# grep "[0-9]" test ##查找所有数字
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# grep "[a-Z]" test ##查找所有字母
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# grep "[^ro]" test ##查找r或者o之外的内容
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# grep "[^0-9]" test ##查找数字之外的内容
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# vim test ##给test文件添加几行,包括空格及空行
root:x:0:0:root:/root:/bin/bash
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
rt
rot
roooooooot
rooot
[root@proxy mnt]# grep "." test ##查找任意字符,发现空格也匹配
root:x:0:0:root:/root:/bin/bash
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
rt
rot
roooooooot
rooot
[root@proxy mnt]# grep ".*" test ##查找任意字符,发现空格及空行也匹配
root:x:0:0:root:/root:/bin/bash
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
rt
rot
roooooooot
rooot
[root@proxy mnt]# grep "roo." test ##找root后面任意1个字符的行
root:x:0:0:root:/root:/bin/bash
roooooooot
rooot
[root@proxy mnt]# grep "ro.." test ##找ro后面任意2个字符的行
root:x:0:0:root:/root:/bin/bash
roooooooot
rooot
[root@proxy mnt]# grep "r..." test ##找r后面任意3个字符的行
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
roooooooot
rooot
[root@proxy mnt]# grep "ro*t" test ##查找rot,其中字母o可以出现任意次,零次也行
root:x:0:0:root:/root:/bin/bash
rt
rot
roooooooot
rooot
[root@proxy mnt]# grep "ro\{1,2\}t" test ##o出现了1~2次
root:x:0:0:root:/root:/bin/bash
rot
[root@proxy mnt]# grep "ro\{3,5\}t" test ##o出现了3~5次
rooot
[root@proxy mnt]# grep "ro\{3,8\}t" test ##出现了3~8次
rooooooooto
rooot
[root@proxy mnt]# grep "ro\{1,8\}t" test ##出现了1~8次
root:x:0:0:root:/root:/bin/bash
rot
roooooooot
rooot
[root@proxy mnt]# grep "ro\{2\}t" test ##o出现了2次
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep "ro\{2,\}t" test ##o出现了2次及3次以上
root:x:0:0:root:/root:/bin/bash
roooooooot
rooot
[root@proxy mnt]# grep "ro\{3,\}t" test ##o出现了3次及3次以上
roooooooot
rooot
[root@proxy mnt]# grep "\(0:\)\{2\}" test ##查找0:0:
root:x:0:0:root:/root:/bin/bash
扩展正则
正则符号 | 含义 |
+ | 最少匹配前一个字符1次 |
? | 最多匹配前一个字符1次 |
{n,m} | 匹配n到m次 |
() | 组合为整体,保留(与正则表达式带括号的效果一样) |
| | 或者 |
\b | 单词边界 |
[root@proxy mnt]# grep "\(0:\)\{2\}" test ##查找0:0:两次
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep "ro\{2\}t" test ##查找前一个字符出现2次
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep -E "ro{2}t" test ##效果同上
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# egrep "ro{2}t" test ##效果同上
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# egrep "ro{1,3}t" test ##查找rot,其中o可以出现1次到3次
root:x:0:0:root:/root:/bin/bash
rot
rooot
[root@proxy mnt]# grep "ro\{1,\}t" test ##查找rot,其中o可以出现1次及1次以上
root:x:0:0:root:/root:/bin/bash
rot
roooooooot
rooot
[root@proxy mnt]# egrep "ro{1,}t" test ##效果同上
root:x:0:0:root:/root:/bin/bash
rot
roooooooot
rooot
[root@proxy mnt]# egrep "ro+t" test ##查找rot其中o最少可以出现1次
root:x:0:0:root:/root:/bin/bash
rot
roooooooot
rooot
[root@proxy mnt]# grep "ro\{0,1\}t" test ##查找rot,其中o可以出现0次到1次
rt
rot
[root@proxy mnt]# egrep "ro{0,1}t" test ##效果同上
rt
rot
[root@proxy mnt]# egrep "ro?t" test ##查找rot,其中o可以出现1次或0次
rt
rot
[root@proxy mnt]# egrep "root|bin" test ##查找有root或者bin的行
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# egrep "^root|^bin" test ##查找以root开头或者以bin开头的行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@proxy mnt]# egrep "^(root|bin)" test ##效果同上
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
{ } 限定次数
- 限定表达式的匹配次数
- {n} {n,m} {n,}
类 型 | 含义 | 示例 | 说明 |
{n} | 匹配n次 | (ab){3} | 匹配ababab |
{n,m} | 匹配n-m次 | (ab){1,3} | 匹配ab, abab, ababab |
{n,} | 匹配至少n次 | (ab){2,} | 匹配2个及以上连续的 ab |
整体及边界匹配
类型 | 含义 | 示例 | 说明 |
\< | 单词的开头 | \<th | 匹配以th开头的单词 |
\> | 单词的结束 | \<root\> | 作用与\broot\b相同 |
\w | 字母数字下划线 | \wa | 匹配xa,不匹配#a |
\s | 匹配空白 | \sa | 匹配 a,不匹配xa |
\d | 匹配数字 | -P\da | 匹配5a,不匹配xa |
\b 在匹配字母时,屏蔽字母,数字,下划线
[root@proxy mnt]# vim abc ##以ABC作为素材
the
1the
$the*
_thea
[root@proxy mnt]# grep "the" abc ##找有the的行
the
1the
$the*
_thea
[root@proxy mnt]# grep "the\b" abc ##找有the且右边不能是字母数字下划线
the
1the
$the*
[root@proxy mnt]# grep "\bthe\b" abc ##找有the且两边不能是字母数字下划线
the
$the*
[root@proxy mnt]# grep "\bthe" abc ##找有the且左边不能是字母数字下划线
the
$the*
sed的基本用法
sed概述:
- Stream EDitor , 流式编辑器
- 非交互式,基于模式匹配过滤及修改文本
- 逐行处理,并将结果输出到屏幕
- 可实现对文本的输出,删除,替换,复制,剪切,导入,导出等各种操作
- 支持正则表达式
命令格式:
- 格式1 : 前置命令 | sed [选项] '(定址i符)指令'
- 格式2 : sed [选项] '(定址i符)指令' 被处理的文档
- 定址符 : 定位哪一行(就是在哪一行去执行这个指令)
- 定址符可以写行号(数字)或者正则表达式
常用命令选项
- -n : 屏蔽默认输出(默认sed会输出读取文档的全部内容)
- -i : 直接修改文件内容(默认sed只是通过内存临时修改文件,源文件无影响)
- -r : 启用扩展正则表达式,若与其他选项一起使用,应作为首个选项
- -e : 指定需要的执行的sed指令,支持使用多个-e参数
- -f : 指定需要执行的脚本文件,需要提前将sed指令写入文件中
常用指令选项
操作符 | 用途 | 指令示例 |
p | 输出 | 2,4p 输出第2, 3, 4行 |
2p;4p 输出第2行, 第4行 | ||
d | 删除 | 2,4d 删除第2行和第4行 |
s | 替换 | s/old/new/ 将每行的第1个old替换为new |
s/old/new/3 将每行的第3个old替换为new | ||
s/old/new/g 将所有的old替换为new |
- = : 输出行号
- "$=" 输出最后一行行号
- ; 分隔前后两条指令
- 替换操作的分隔"//" 可改用其他字符,键盘上1-0的特殊字符,例如:!@#$%^&*()
命令格式解析
- 条件,可以是行号或正则表达式
- 行号可以使用单个数字表示当前行
- 或者3,5表示连续的多行
- 省略条件,则默认逐行处理全部文本
- 匹配正则时,需要使用//
- 默认sed会将所有输出的内容都打印出来,可以使用-n屏蔽默认输出
- 选项中可以使用-r选项,让sed支持扩展正则
输出文本练习:
[root@proxy mnt]# cat test ##以test文件作为素材
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# sed 'p' test ##输出+默认输出,所以是每行出现2次
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed -n 'p' test ## 输出全文
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# sed -n '1p' test ##输出第一行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# sed -n '2p' test ##输出第二行
bin:x:1:1:bin:/bin:/sbin/nologin
[root@proxy mnt]# sed -n '3p' test ##输出第三行
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@proxy mnt]# sed -n '1,3p' test ##输出1-3行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@proxy mnt]# sed -n '1p;3p' test ##输出第1行和第3行
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@proxy mnt]# sed -n '1,+2p' test ##输出第1行以及后面2行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@proxy mnt]# sed -n '3,+1p' test ##输出第3行以及后面1行
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@proxy mnt]# sed -n '1~2p' test ##输出奇数行
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed -n '2~2p' test ##输出偶数行
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@proxy mnt]# sed -n '/root/p' test ##输出有root的行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# sed -n '/^root/p' test ##输出以root开头的行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# free | sed -n '2p' ##输出free指令生成的文档的第2行
Mem: 1446924 70232 1108292 8608 268400 1211636
[root@proxy mnt]# sed -rn '/root|bin/p' test ##输出有root或者有bin的行
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# sed -n '$=' test ##输出全文最后1行行号
5
删除文本练习:
[root@proxy mnt]# sed 'd' test ##删除全文
[root@proxy mnt]# sed '1d' test ##删除第1行,显示剩余行
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
[root@proxy mnt]# sed '2d' test ##删除第2行,
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# sed '5d' test ##删除第5行
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# sed '1,3d' test ##删除1-3行
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '3,+2d' test ##删除第3行以及后面2行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@proxy mnt]# sed '/bash$/d' test ##删除以bash结尾的行
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
[root@proxy mnt]# sed '1d;3d' test ##删除第1行和第3行
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '1~2d' test ##删除奇数行
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@proxy mnt]# sed '2~2d' test ##删除偶数行
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '$d' test ##删除全文最后1行
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# sed '/var/!d' test ##不删除有var的行
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
替换练习:
[root@proxy mnt]# vim hihi ##以hihi作为素材
2017 2011 2018
2017 2017 2024
2017 2017 2017
[root@proxy mnt]# sed 's/2017/xxxx/' hihi ##将所有行的第1个2017替换成xxxx
xxxx 2011 2018
xxxx 2017 2024
xxxx 2017 2017
[root@proxy mnt]# sed 's/2017/xxxx/2' hihi ##将全文的第2列的2017替换成xxxx
2017 2011 2018
2017 xxxx 2024
2017 xxxx 2017
[root@proxy mnt]# sed 's/2017/xxxx/g' hihi ##将全文的2017替换成xxxx
xxxx 2011 2018
xxxx xxxx 2024
xxxx xxxx xxxx
[root@proxy mnt]# sed '2s/2017/xxxx/' hihi ##将第2行的第1个2017替换成xxxx
2017 2011 2018
xxxx 2017 2024
2017 2017 2017
[root@proxy mnt]# sed '3s/2017/xxxx/2' hihi ##将第3行的第2个2017替换成xxxx
2017 2011 2018
2017 2017 2024
2017 xxxx 2017
[root@proxy mnt]# sed '3s/2017//2' hihi ##潜在的删除功能,将第3行的第2个2017替换成空
2017 2011 2018
2017 2017 2024
2017 2017
[root@proxy mnt]# sed 's/2024/xxxx/p' hihi ##将所有行的2024替换成xxxx
2017 2011 2018
2017 2017 xxxx
2017 2017 xxxx
2017 2017 2017
1.如何把/bin/bash换成/sbin/sh?
[root@proxy mnt]# cat test ##以test作为素材
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# sed 's/\/bin\/bash/\/sbin\/sh/' test ##正常替换,繁琐
root:x:0:0:root:/root:/sbin/sh
[root@proxy mnt]# sed 's#/bin/bash#/sbin/sh#' test ##修改替换符,简洁
root:x:0:0:root:/root:/sbin/sh
2.删除文件中每行的第二个、最后一个字符
[root@proxy mnt]# cat nns ##以nns文件作为素材
Hello the world
ni hao ma beijing
[root@proxy mnt]# sed 's/.//2' nns ##删除全文第2个字符
Hllo the world
n hao ma beijing
[root@proxy mnt]# sed 's/.$//' nns ##删除全文最后1个字符
Hello the worl
ni hao ma beijin
[root@proxy mnt]# sed 's/.//2;s/.$//' nns ##组合在一起就是删除全文的第2个和最后1个字符
Hllo the worl
n hao ma beijin
3.将文件中每行的第一个、倒数第1个字符互换
[root@proxy mnt]# cat abc ##以abc 文件作为素材
abc
xyz
[root@proxy mnt]# sed -r 's/(a)(b)(c)/\3\2\1/' abc ##替换abc为cba
cba
xyz
[root@proxy mnt]# sed -r 's/(^.)(.*)(.$)/\3\2\1/' abc ##将全文每行的第一个、倒数第1个字符互换
cba
zyx
4.删除文件中所有的数字
[root@proxy mnt]# cat nns ##以nns作为素材
He4llo t5he world
nI hao m7A Beijing
[root@proxy mnt]# sed -i 's/[0-9]//g' nns ##删除全文数字
[root@proxy mnt]# cat nns
Hello the world
nI hao ma beijing
5.为文件中每个大写字母添加括号
[root@proxy mnt]# cat nns ##以nns作为素材
Hello the world
nI hao mA Beijing
[root@proxy mnt]# sed -r 's/([A-Z])/(\1)/g' nns ##添加小括号
(H)ello the worl(D)
n(I) hao m(A) b(E)ijing
[root@proxy mnt]# sed -r 's/([A-Z])/{\1}/g' nns ##添加花括号
{H}ello the worl{D}
n{I} hao m{A} b{E}ijing
[root@proxy mnt]# sed -r 's/([A-Z])/[\1]/g' nns ##添加中括号
[H]ello the worl[D]
n[I] hao m[A] b[E]ijing
编写脚本,实现ftp服务的安装过程到使用,要支持匿名上传(从pub目录)
[root@proxy mnt]# vim test03.sh
#!/bin/bash
#这是一个简单的ftp服务
if [ "$USER" != "root" ];then
echo "你不是管理员,没有权限哦!"
exit 2
fi
rpm -q vsftpd
if [ $? -ne 0 ];then
yum -y install vsftpd &> /dev/null
sed -i '/^#anon_upl/s/#//' /etc/vsftpd/vsftpd.conf
systemctl restart vsftpd
systemctl enable vsftpd &> /dev/null
chmod 777 /var/ftp/pub
#setenforce 0 ##安装有防火墙就需要这2行
#systemctl stop firewalld
else
echo "请稍等..."
sed -i '/^#anon_upl/s/#//' /etc/vsftpd/vsftpd.conf
systemctl restart vsftpd
systemctl enable vsftpd &> /dev/null
chmod 777 /var/ftp/pub
#setenforce 0 ##安装有防火墙就需要这2行
#systemctl stop firewalld
fi
sed文本块处理
操作符 | 用途 | 指令示例 |
i | 行前追加 | 2iYY 在第2行之前添加文本行 "YY" |
4,7iYY 在第4-7行的每一行前添加文本行 | ||
a | 行后追加 | 2aYY 在第2行之后添加文本 |
/^XX/aYY 在以XX开头的行之后添加文本 | ||
c | 替换当前行 | 2cYY 将第2行的内容修改为 "YY" |
处理多行文本
修改后的文本有多行时
- 以换行符 \n 分隔
- 或者,使用 \ 强制换行
a行后追加练习:
[root@proxy mnt]# sed 'a666' test ##所有行后添加一行666
root:x:0:0:root:/root:/bin/bash
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
666
[root@proxy mnt]# sed '1a 666' test ##第1行后添加一行666
root:x:0:0:root:/root:/bin/bash
666
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
[root@proxy mnt]# sed '2,3a 666' test ##第2~3行后添加一行666
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '/bin/a 666' test ##在有bin的行后添加一行666
root:x:0:0:root:/root:/bin/bash
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
666
[root@proxy mnt]# sed '/^bin/a 666' test ##以bin开头的行后添加一行666
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
666
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
[root@proxy mnt]# sed -e '2a 666' -e '4a 666' test ##第2行和第4行行后添加666
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
i行前追加练习:
[root@proxy mnt]# sed 'i 666' test ##所有行前添加一行666
666
root:x:0:0:root:/root:/bin/bash
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '2,+1i 666' test ##第2~3行前添加一行666
root:x:0:0:root:/root:/bin/bash
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
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
[root@proxy mnt]# sed '/root/i 666' test ##有root的行前添加一行666
666
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# sed '/^root/i 666' test ##以root开头的行添加一行666
666
root:x:0:0:root:/root:/bin/bash
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
[root@proxy mnt]# sed '2i 666' test ##第2行前添加一行666
root:x:0:0:root:/root:/bin/bash
666
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
c替换当前行练习:
[root@proxy mnt]# sed 'c 666' test ##替换全文所有行为666
666
666
666
666
666
[root@proxy mnt]# sed '4c 666' test ##替换第四行为666
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '$c 666' test ##替换最后一行为666
root:x:0:0:root:/root:/bin/bash
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
666
[root@proxy mnt]# sed '/root/c 666' test ##找有root的行替换为666
666
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
[root@proxy mnt]# sed '/^bin/c 666' test ##以bin开头的行替换为666
root:x:0:0:root:/root:/bin/bash
666
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
sed高级应用
导入导出操作
- r 动作应结合 -i 选项才会存入,否则只输出
- w 动作以覆盖的方式另存为新文件
操作符 | 用途 | 指令示例 |
r | 读取文件 | 3r b.txt 在第3行下方添加文件b.txt |
4,7r b.txt 在第4-7行后添加文件b.txt | ||
w | 保存到文件 | 3w c.txt 将第3行另存为文件c.txt |
4,7w c.txt 将第4-7行另存为文件c.txt |
!取反操作
用途
- 根据定址条件取反
示例
- 列出不使用bash的用户账号记录
[root@proxy mnt]# sed -n '/bash$/!p' /etc/passwd ##输出不是以bash结尾的行
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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
......
sed综合脚本应用
问题
- 找到使用bash作登录Shell的本地用户
- 列出这些用户的shadow密码记录
- 按每行“用户名 --> 密码记录”保存到getupwd.log,如图所示
方案:
- 先用sed工具取出登录Shell为/bin/bash的用户记录,保存为临时文件/tmp/urec.tmp,并计算记录数量
- 再结合while循环遍历取得的账号记录,逐行进行处理
- 针对每一行用户记录,采用掐头去尾的方式获得用户名、密码字串
- 按照指定格式追加到/tmp/getuupwd.log文件
- 结束循环后删除临时文件,报告分析结果
[root@proxy mnt]# vim ./getupwd.sh
#/bin/bash
A=$(sed -n '/bash$/s/:.*//p' /etc/passwd) ## 提取符合条件的账号记录
for i in $A ##遍历账号记录
do
pass1=$(grep $i /etc/shadow)
pass2=${pass1#*:}
pass=${pass2%%:*}
echo "$i --> $pass"
done
[root@proxy mnt]# bash getupwd.sh ##效果如图所示!!!