正则表达式概念:
正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串,简单来说,
是一种匹配字符串的方法,通过一些特殊符号,实现快速查找、删除、替换某个特定字符串。
基础正则表达式:
基础正则表达式是常用正则表达式最基础的部分。在 Linux 系统中常见的文件
处理工具中 grep 与 sed 支持基础正则表达式,而 egrep 与 awk 支持扩展正则表达式。
标准正则表达式:grep
扩展正则表达式:egrep
Linux命令三剑客:
grep
sed
awk
- grep:过滤
- -v:取反
- -n:显示行号
- -i:不区分大小写
- [ ]:查找集合字符,中括号内不管写几个字符,都只匹配一个,表示匹配其中的任何一个字符
- [^]:取反,例如[^a-z],表示查找不是以小写字母开头的文本
- ^[ ]:表示以括号中的字符开头
- \.$:查看以“.”结尾的内容
- ^$:查看空行
查找任意字符和重复字符
查找包含四字符的单词的行,单词以w开头,d结尾
注意:一个点代表一个字符
查找至少包含两个字母o(oo)的字符串的行
注释:
ooo*:前两个o是条件,表示包含两个o;然后是o*,表示后面有零个或多个重复o
查找行,行中单词包含w开头和d结尾,中间至少一个字母o
查询以w开头,d结尾,中间字符可有可无
查询包含数字的行
查询包含两个o的字符
注释:
'o\{2\}':表示两个字母o
w开头,d结尾中间有2--5个o
w开头,d结尾中间有2个以上o
- egrep:扩展正则表达式
文本处理器sed
sed(Stream EDitor)是一个强大而简单的文本解析转换工具,可以读取文本,并根据
指定的条件对文本内容进行编辑(删除、替换、添加、移动等),最后输出所有行或者仅输
出处理的某些行。sed 也可以在无交互的情况下实现相当复杂的文本处理操作,被广泛应用
于 Shell 脚本中,用以完成各种自动化处理任务。
sed 的工作流程主要包括读取、执行和显示三个过程。
Ø 读取:sed 从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)。
Ø 执行:默认情况下,所有的 sed 命令都在模式空间中顺序地执行,除非指定了行的地址,否则 sed 命令将会在所有的行上依次执行。
Ø 显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。
- sed:文本流处理工具,过滤、编辑
- -n:安静模式,仅显示结果,对文本内容不做修改
- ‘p’:打印
- ‘p;n’:打印奇数行
- ‘n;p’:打印偶数行
- {p;n}:指定打印的行数中的奇数行
- {n;p}:指定打印行数中的偶数行
- //:查找单词时要用这个符号夹住
- d:删除,在单引号内部后边
- s:替换,在单引号内部前边
- {H;d};$G:文本内容的迁移,移动
- a:添加,在指定行的下一行添加
- i:添加,在指定行的上一行添加
- c:取代行,
3:输出符合条件的文本
(1)输出所有内容
[root@localhost ~]# sed -n 'p' test.txt
(2)输出第三行
[root@localhost ~]# sed -n '3p' test.txt
(3)输出3~5行
[root@localhost ~]# sed -n '3,5p' test.txt
(4)输出所有奇数行
[root@localhost ~]# sed -n 'p;n' test.txt
(5)输出所有偶数行
[root@localhost ~]# sed -n 'n;p' test.txt
(6)输出第1~5行之间的奇数行
[root@localhost ~]# sed -n '1,5{p;n}' test.txt
(7)输出第10行至文件尾之间的偶数行
[root@localhost ~]# sed -n '10,${n;p}' test.txt
注释:
此命令中,读取的第一行是文件的第10行,读取的第二行,是文件的第11行,依次类推
(8)输出包含the的行
[root@localhost ~]# sed -n '/the/p' test.txt
(9)输出从第4行开始至第一个包含the的行
[root@localhost ~]# sed -n ' 4,/the/p' test.txt
(10)输出包含the的行所在的行号
[root@localhost ~]# sed -n '/the/=' test.txt
注释:
=用来输出行号
(11)输出以PI开头的行
[root@localhost ~]# sed -n '/^PI/p' test.txt
(12)输出包含单词wood的行
[root@localhost ~]# sed -n '/\/p' test.txt
4:删除符合条件的文本
(1)删除第3行
[root@localhost ~]# nl test.txt | sed '3d' ##显示行号
或
[root@localhost ~]# sed '3d' test.txt ##不显示行号
(2)删除3~5行
[root@localhost ~]# nl test.txt |sed '3,5d'
(3)删除包含cross的行
[root@localhost ~]# nl test.txt |sed '/cross/d'
注释:删除不包含cross的行
[root@localhost ~]# nl test.txt |sed '/cross/! d'
(4)删除以小写字母开头的行
[root@localhost ~]# sed '/^[a-z]/d' test.txt
(5)删除以点结尾的行
[root@localhost ~]# sed '/\.$/d' test.txt
(6)删除空行
[root@localhost ~]# sed '/^$/d' test.txt
5:替换符合条件的文本
(1)将每行的第一个the换成THE
[root@localhost ~]# sed 's/the/THE/' test.txt
(2)将每行中的第2个l换成L
[root@localhost ~]# sed 's/l/L/2' test.txt
(3)将文中所有的the换成THE
[root@localhost ~]# sed 's/the/THE/g' test.txt
(4)将文中所有的o删除
[root@localhost ~]# sed 's/o//g' test.txt
(5)在每行的行首插入#
[root@localhost ~]# sed 's/^/#/' test.txt
注释
在每行行尾添加#
[root@localhost ~]# sed 's/$/#/' test.txt
(6)在包含the的每行的行首插入#
[root@localhost ~]# sed '/the/s/^/#/' test.txt
(7)在每行的行尾插入字符串EOF
[root@localhost ~]# sed 's/$/EOF/' test.txt
(8)将第3~5行中的所有the替换成THE
[root@localhost ~]# sed '3,5s/the/THE/g' test.txt
(9)将包含the的所有行中的o都替换成O
[root@localhost ~]# sed '/the/s/o/O/g' test.txt
5:迁移符合条件的文本
H:复制到剪切板
g:将剪切板中的内容覆盖到指定行
G:将剪切板中的内容追加到指定行
w:保存文件
r:读取指定文件
a:追加指定内容
(1)将包含the的行迁移至文件的末尾
[root@localhost ~]# sed '/the/{H;d};$G' test.txt
(2)将第1~5行的内容转移至第17行后
[root@localhost ~]# sed '1,5{H;d};17G' test.txt
(3)将包含the的行另存为文件out.txt
[root@localhost ~]# sed '/the/w out.txt' test.txt
(4)将文件/etc/hostname的内容添加到包含the的每一行后
[root@localhost ~]# sed '/the/r /etc/hostname' test.txt
(5)在第3行后插入一个新行,内容为#chkconfig:35 82 20
[root@localhost ~]# sed '3a#chkconfig:35 82 20' test.txt
(6)在包含the的每行后插入一个新行,内容为New
[root@localhost ~]# sed '/the/aNew' test.txt
(7)在第3行后插入多行内容
[root@localhost ~]# sed '3aNew1\nNew2' test.txt
注释:\n为换行,添加两行为New1和New2
- awk:过滤列
- -F:过滤指定的符号文本处理器awk
awk 是一个功能强大的编辑工具,逐行读取输入文本,并根据
指定的匹配模式进行查找,对符合条件的内容进行格式化输出或者过滤处理
1:awk常见用法
$0 表示整个当前行
$1 每行第一个字段
NF 字段数量变量
NR 每行的记录号,多文件记录递增
FNR 与NR类似,不过多文件记录不递增,每个文件都从1开始
\t 制表符
\n 换行符
FS BEGIN时定义分隔符
RS 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~ 匹配,与==相比不是精确比较
!~ 不匹配,不精确比较
== 等于,必须全部相等,精确比较
!= 不等于,精确比较
&& 逻辑与
|| 逻辑或
+ 匹配时表示1个或1个以上
/[0-9][0-9]+/ 两个或两个以上数字
/[0-9][0-9]*/ 一个或一个以上数字
FILENAME 文件名
OFS 输出字段分隔符, 默认也是空格,可以改为制表符等
ORS 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F'[:#/]' 定义三个分隔符
2:awk案例
(1)按行输出文本
awk -F":" '{print}' /etc/passwd //输出所有
awk -F":" '{print $0}' /etc/passwd //输出所有
awk -F: 'NR==3,NR==6{print}' /etc/passwd //显示第3行到第6行
awk -F: 'NR>=3&&NR
awk -F: 'NR==3||NR==6{print}' /etc/passwd //显示第3行和第6行
awk '(NR%2)==1{print}' /etc/passwd //显示奇数行
awk '(NR%2)==0{print}' /etc/passwd //显示偶数行
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结尾的行数
awk 'BEGIN{RS=""};END{print NR}' /etc/ssh/sshd_config //统计以空行分隔的文本段落数
awk '{print NR,$0}' /etc/passwd //输出每行的行号
awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd //依次打印行号,字段数,最后字段值,制表符,每行内容
awk -F: 'NR==5{print}' /etc/passwd //显示第5行
route -n|awk 'NR!=1{print}' //不显示第一行
awk -F: '{print NF}' /etc/passwd //显示每行有多少字段
awk -F: '{print $NF}' /etc/passwd //将每行第NF个字段的值打印出来
awk -F: 'NF==4 {print }' /etc/passwd //显示只有4个字段的行
awk -F: 'NF>2{print $0}' /etc/passwd //显示每行字段数量大于2的行
(2)按字段输出文本
awk -F":" '{print $3}' /etc/passwd //显示第三列
awk -F":" '{print $1 $3}' /etc/passwd //$1与$3相连输出,无空格,
awk -F":" '{print $1,$3}' /etc/passwd //多了一个逗号,输出第1和第3个字段,有空格
awk -F: '$2=="!!" {print}' /etc/shadow //统计密码为空的shadow记录
awk 'BEGIN {FS=":"}; $2=="!!" {print}' /etc/shadow ##显示密码为空的用户的shadow信息
awk -F ":" '$7~"/bash" {print $1}' /etc/passwd ##显示第七个字段为/bash的行的第一个字段
awk -F: 'NR==5{print}' /etc/passwd //显示第5行
awk -F":" '{print $1 " " $3}' /etc/passwd //$1与$3之间手动添加空格分隔
(3)通过管道、双引号调用shell命令
awk -F: '/bash$/{print | "wc -l"}' /etc/passwd ##统计bash用户的个数
awk 'BEGIN {while ("w" | getline) n++ ; {print n-2}}' ##统计在线用户的数量
awk 'BEGIN {"hostname" | getline;print $0}' ##输出当前主机名
awk -F: '$1~/mail/ && $3>6 {print }' /etc/passwd //逻辑与,$1匹配mail,并且$3>6
awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd
awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd //逻辑或,统计以mail开头或第3列大于1000的行
awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd
sort 工具
在 Linux 系统中,常用的文件排序工具有三种:sort、uniq、wc 。本章将介绍前两种
工具的用法。
sort 是一个以行为单位对文件内容进行排序的工具,也可以根据不同的数据类型来排
序。例如数据和字符的排序就不一样。sort 命令的语法为“sort [选项] 参数”,其中常用的选
项包括以下几种。
Ø -f:忽略大小写;
Ø -b:忽略每行前面的空格;
Ø -M:按照月份进行排序;
Ø -n:按照数字进行排序;
Ø -r:反向排序;
Ø -u:等同于 uniq,表示相同的数据仅显示一行;
Ø -t:指定分隔符,默认使用[Tab]键分隔;
Ø -o :将排序后的结果转存至指定文件;
Ø -k:指定排序区域。
示例 1:将/etc/passwd 文件中的账号进行排序。
[root@localhost ~]# sort /etc/passwd
示例 2:将/etc/passwd 文件中第三列进行反向排序。
[root@localhost ~]# sort -t ':' -rk 3 /etc/passwd
备注:
Ø -r:反向排序;
Ø -t:指定分隔符,默认使用[Tab]键分隔;
Ø -k:指定排序区域。
示例 3:将/etc/passwd 文件中第三列进行排序,并将输出内容保存至 user.txt 文件中。
[root@localhost ~]# sort -t ':' -k 3 /etc/passwd -o user.txt
[root@localhost ~]# cat user.txt
备注:
Ø -t:指定分隔符,默认使用[Tab]键分隔;
Ø -k:指定排序区域。
4.2.4 uniq 工具
Uniq 工具在 Linux 系统中通常与 sort 命令结合使用,用于报告或者忽略文件中的重复
行。具体的命令语法格式为:uniq [选项] 参数。其中常用选项包括以下几种。
Ø -c:进行计数;
Ø -d:仅显示重复行;
Ø -u:仅显示出现一次的行。
示例 1:删除 testfile 文件中的重复行
[root@localhost ~]# cat testfile
Linux 10
Linux 20
Linux 30
Linux 30
Linux 30
CentOS 6.5
CentOS 6.5
CentOS 6.5
CentOS 7.3
CentOS 7.3
CentOS 7.3
[root@localhost ~]# uniq testfile
Linux 10
Linux 20
Linux 30
CentOS 6.5
CentOS 7.3
示例 2:删除 testfile 文件中的重复行,并在行首显示该行重复出现的次数。
[root@localhost ~]# uniq -c testfile
1 Linux 10
1 Linux 20
3 Linux 30
3 CentOS 6.5
3 CentOS 7.3
备注:
Ø -c:进行计数;
示例 3:查找 testfile 文件中的重复行。
[root@localhost ~]# uniq -d testfile
Linux 30
CentOS 6.5
CentOS 7.3
备注:
Ø -d:仅显示重复行;
4.2.5 tr 工具
tr 命令常用来对来自标准输入的字符进行替换、压缩和删除。可以将一组字符替换之后
变成另一组字符,经常用来编写优美的单行命令,作用很强大。
其常用选项包括以下内容。
Ø -c:取代所有不属于第一字符集的字符;
Ø -d:删除所有属于第一字符集的字符;
Ø -s:把连续重复的字符以单独一个字符表示;
Ø -t:先删除第一字符集较第二字符集多出的字符。
示例 1:将输入字符由大写转换为小写。
[root@localhost ~]# echo "KGC" | tr 'A-Z' 'a-z'
kgc
示例 2:压缩输入中重复的字符。
[root@localhost ~]# echo "thissss is a text linnnnnnne." | tr -s 'sn'
this is a text line.
备注:
Ø -s:把连续重复的字符以单独一个字符表示;
示例 3:删除字符串中某些字符。
[root@localhost ~]# echo 'hello world' | tr -d 'od'
hell wrl
备注:
Ø -d:删除所有属于第一字符集的字符;