了解shell正则表达式!!!!!
1.正则表达式
shell文本编辑三剑客:grep,sed, awk;
正则表达式分为:基础正则表达式与扩展正则表达式,它不是一个字符串处处理的依据标准,是使用单个字符串搜索,匹配一系列的符合某个语法规则的字符串。
它由普通字符(a~z)以及特殊字符(元字符)组成。
1.1基础正则表达式
注:红框内是固定格式;
1.1.2 举例
命令 | 结果 |
---|---|
grep -n ‘the’ as.txt | 筛选出文件包含的the的行 |
grep -in ‘the’ as.txt | 筛选出文件包含的the不区分大小写 |
grep -vn ‘the’ as.txt | 筛选出不包含the的行,v是反向选择 |
grep -n ‘sh[io]rt’ as.txt | 筛选文件中sh带有i或o的字符的行 |
grep -n ‘oo’ as.txt | 查找文件包含的重复单个字符oo |
grep -n ‘[^w] oo’ as.txt | 查找oo前面不是w的字符串(是aa前面的字符是符合匹配) |
grep -n ‘[^a-z]oo’ as.txt | 查找oo前面不是小写字母的字符(A-Z)是大写字母 |
grep -n ‘[0-9]’ as.txt | 查找包含数字的行 |
grep -n ‘^the’ as.txt | 查找行首the开头的字符行 |
grep -n ‘a$’ as.txt | 查找结尾为a的字符行 |
grep -n ‘^ [ a-z ]’ as.txt | 查找以小写字母的开头的行,(大写是A-Z)注意^是在[]外面哦 |
grep -n ‘^$’ as.txt | 查询空行 |
grep -n ‘w…d’ as.txt | 查询任意一个字符. |
grep -n ‘ooo*’ as,txt | 查询重复的字符,可以使用* |
grep -n ‘woo*d’ as.txt | 查询以w开头,d结尾,中间至少包含一个o的字符串 |
grep -n ‘w.*d’ as.txt | 查询w开头,d结尾。中间的字符可有可无的字符串 |
grep -n ‘o \ {2\ }’ as.txt | 查询两个o的字符 |
grep -n ‘wo\ {2,5\ }d’ as.txt | 查询w开头,d结尾,中间包含的2~5个o的字符串 |
grep -n ‘wo\ {2,\ }d’ as.txt | 查询w开头,d结尾,中间包含的2个或2个以上的o字符串 |
1.2扩展正则表达式
2. sed工具
- sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。
- sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中
- 文本处理工具,读取文本内容,根据指定条件进行处理,如:删除,替换,添加等
- 可在无交互的情况下实现相当复杂的文本处理操作
- 被广泛应用于shell脚本,以完成自动化处理任务
- sed依赖于正则表达式
- 工作的原理
读取-----------执行-------------显示
在所有文件内容都被处理完成之前,上面的流程将重复执行,直至所有的内容被处理完。
!!!!!!!注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输的文件并不会发生任何变化,除非是用重定向存储输出,或者 -i 直接编制文本文件;最好做编辑时把原文件备份一下;
2.1 命令格式
-
sed -e ‘编辑指令’ 文件1 文件2
-
sed -n -e ‘编辑指令’ 文件1 文件2
-
sed -f 脚本文件 文件1 文件2
-
sed -i -e ‘编辑指令’ 文件1 文件2
常用选项
选项 | 作用 |
---|---|
-e | 指定要执行的命令,只有一个编辑命令是可以省略 |
-n | 只输出处理后的行,读入时不显示 |
-i | 直接编辑文件,而不输出结果 |
-f | 用指定的脚本文件来处理输入的文本文件 |
-h | 显示帮助 |
编辑格式
[n1,[n2]] 操作 [参数]
- n1:可以是数字,正则表达式,$, 没有代表所有行
- 操作:可以是a,c,d,p,s,r,w,i,s,y,等
- 参数:一般有g,代表只要符合条件的全部进行处理
- 常用操作:
2.2 举例
以as.txt文本为例!!!
- 输出
- 删除
- 替换
- 迁移
输出
sed -n ‘p’ as.txt | 输出所有内容,等同于cat as.txt |
sed -n ‘3p’ as.txt | 输出第三行 |
sed -n ‘3,5p’ as.txt | 输出第3~5行 |
sed -n ‘p;n’ as.txt | 输出第所有奇数行,n表示读入下一行资料 |
sed -n ‘n;p’ as.txt | 输出第所有偶数行,n表示读入下一行资料 |
sed -n ‘1,5{p;n}’ as.txt | 输出第 1~5 行之间的奇数行(第 1、3、5 行) |
sed -n ‘10,${n;p}’ as.txt | 输出第 10 行至文件尾之间的偶数行 |
sed -n ‘/the/p’ as.txt | 输出包含the 的行 |
sed -n ‘/the/=’ as.txt | 输出包含the 的行所在的行号,等号(=)用来输出行号 |
sed -n ‘/[0-9]$/p’ as.txt | 输出以数字结尾的行 |
删除
下面命令中 nl 命令用于计算文件的行数,结合该命令可以更加直观地查看到命令执行的结果。可以先nl看下,然后在删除;
注:根据不同选项结合起来,实现不同的效果
nl as.txt | sed ‘3d’ |
nl as.txt | sed ‘3,5d’ |
sed ‘d’ as.txt | 全删 |
sed ‘$d’ as.txt | 删除结尾最后一行 |
sed ‘^$d’ as.txt | 删除空行 |
sed ‘/bash$/d’ /etc/passwd | 删除结尾含有bash的行 |
sed ‘/nologin$/!d’ /etc/passwd | 不删除含有nologin的,其他的都删除 |
sed ‘/2/, /3/d’ as.txt | 从第一个包含数字2的行,一直删除到包含数字3结束,注:(如果数字3之后,还有数字2,那么继续从第一个数字2开始删除,知道删除到包含数字3结束或没有3删除全部后结束) |
替换:
s | 字符串替换 |
c | 整行/整块替换 |
y | 字符转换 |
g | 表明新字符串将会替换所有匹配地方 |
p | 打印与替换命令匹配的行,与-n一起使用 |
w | 文件:将替换的结果写到文件中 |
sed -n ‘s/root/admin/p’ /etc/passwod | 将文件内的带有root的改成admin并打印出来,只更改第一个root |
sed -n ‘s/root/admin/gp’ /etc/passwod | +g将文件内的带有root的都改成admin并打印出来, |
sed -n ‘s/root/admin/2p’ /etc/passwod | 将带有root行的第2个root的替换,第一个root不替换 |
sed -n ‘s/root/ /gp’ /etc/passwd | 将所有root替换成空格,也可以理解为删除,删除不就变成空格了嘛 |
sed -n ‘/^root/ s/$/#/p’ /etc/passwd | 将开头是root的行,结尾$替换成# |
sed -n ‘1,20 s/^/#/p’ /etc/passwd | 将文件内1到20行开头替换成# |
sed -f sc.sed /etc/passwd | 对文件 执行脚本文件内的sed命令 |
sed ‘1,10w as.txt’ /etc/passwd | 将文件的1到10行保存到另一个文本文件内 |
sed ‘1,10 s/^/#/w as.txt’ /etc/passwd | 将文件的1到10行开头替换成#保存到as.txt文件内(会覆盖原有的内容哦) |
sed ‘/root/c abc’ | 将包含root的整行,替换成abc |
sed ‘/root/ y/root/abbb/’ | 将包含root的字符,同等字符长度的替换,root=4 ,abbb=4 |
迁移插入
H | 复制到剪贴板 |
G | 将复制的数据粘贴到指定行 |
r | 读取指定文件 |
a | 追加指定内容 |
sed ‘$a ABC’ /etc/passwd | 在文件结尾追加ABC |
sed ‘1i ABC’ /etc/passwd | 在文件第一行插入ABC |
sed ‘5r /root/hg.txt’ /etc/passwd | 在/etc/passwd文件中第五行读取root下的文本文件hg.txt |
sed ‘/root/{H;d};$G’ /etc/passwd | 将包含root的行复制后,删除原有的行,粘贴到结尾 |
sed ‘1,5H;15,16G’ /etc/passwd | 将文件第一行到第五行复制,分别粘贴到15行,16行下 |
3.awk
- 工作原理:逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令;
- sed命令常用于一整行的整理,而awk比较倾向将一行分成多个字段 然后在进行处理。
- awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。
- 在使用awk命令的过程中,可以使用逻辑操作符&&表示与,||表示或,!表示非;还可以进行简单的数学运算,+ ,-, *,/,%,^ 分别表示加,减,乘,除,取余,乘方,
3.1命令格式
awk 选项 ‘模式或条件’ {操作} 文件1 文件2
awk -f 脚本文件 文件1 文件2
3.2常见内建变量
3.3举例
按行输出
awk ‘{print}’ as.txt | 输出所有内容 |
awk ‘{print $0}’ as.txt | 输出所有内容 |
awk ‘NR==1{print}’ as.txt | 输出第一行内容 |
awk ‘NR= =1,NR= =3{print}’ as.txt | 输出第一行到第三行内容 |
awk ‘NR= =1 双管道符竖杠NR= =3{print}’ as.txt | 输出第一行和第三行内容 |
awk ‘(NR%2)==1{print}’ as.txt | 输出所有奇数行的内容,行数除以2余1的话就是说明是奇数; |
awk ‘(NR%2)==0{print}’ as.txt | 输出所有偶数行的内容,行数除以2余0的话就是说明是偶数; |
awk ‘/^root/{print}’ /etc/passwd | 输出以root开头的行 |
awk ‘/nologin$/{print]’ /etc/passwd | 输出以nologin结尾的行 |
awk ‘BEGIN {x=0}; //bin\ /bash$/{x++};END {print x}’ /etc/passwd | 统计以/bin/bash结尾的行,先执行BEGIN定义的x是0,有一个以/bin/bash结尾的行x就+1,最后执行END 打印x是多少 |
按字段输出文本
awk -F “:” ‘{print $3}’ /etc/passwd | 输出每行中(以空格或制表符分隔的第三个字段) |
awk -F “:” ‘{print $1 $3}’ /etc/passwd | 输出每行的第1,3个字段 |
awk -F “:” ‘$3<5{print $1,$3}’ /etc/passwd | 输出第三个字段小于5的第一个,第三个字段 |
awk -F “:” {max=($3>$4)? $3: $4;{print max}}’ /etc/passwd | 三元运算符,如果第三个字段的值大于第四个字段的值,则把第三个字段的值赋给max,否则第四个字段的值复制给max |
awk -F “:” ‘{print NR,$0}’ /etc/passwd | 输出全部行号和全部内容 |
awk -F “:” ‘($1~“root”) && (NF==7){print $1,$2}’ /etc/passwd | 输出第一个字段包含root且有七个字段的第1,2字段 |
awk -F “:” ‘($7!="/bin/bash") && ($7!="/sbin/nologin") {print}’ /etc/passwd | 输出第七个字段不包含/bin/bash,也不包含/sbin/nologin的所有行 |
通过管道,双引号调用shell命令:
-
echo $ PATH | awk ‘BEGIN{RS=":"};END{print NR}’
统计以冒号分隔的文本段落数,END{}语句块中,往往会放入打印结果; -
awk -F : ‘/bash$ /{print | "wc -l "}’ /etc/passwd
调用wc -l 命令统计使用/bash结尾的用户个数,同grep -c ‘bash$’ /etc/passwd 相同 -
awk ‘BEGIN {while(“w” | getline) n++; {print n-2}}’
调用w命令,并用来统计当前在线用户 -
awk ‘BEGIN {“hostname”| getline ; print $0}’
调用hostname,并输出当前主机名 -
当getline左右无重定向符< 或 | 时,getline用于当前的文件,读入当前文件的第一行给其后面的的变量var或$0;应该注意到,由于awk在处理getline之前已经读了一行,所以getline得到的返回结果是隔行的。
-
当getline左右有定向符,getline用于定向输入文件,由于该文件是刚打开的,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。
4.注释
还有其他工具,sort ,uniq, tr 咱们主要解释三剑客,感兴趣的博友可以去了解下另三种!!!!