命令与正则表达式

260 阅读8分钟

1.正则表达式的概念

正则表达式,又称规则表达式(英语:Regular Expression),在代码中常简写为regex、 regexp或RE),是计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

正则表达式不只有一种,而且 LINUX中不同的程序可能会使用不同的正则表达式,如:工具: grep sed awk egrep

LINUX 中常用的有两种正则表达式引擎砖础:正则表达式:BRE 扩展正则表达式:ERE 正则表达式是由普通字符元字符组成:

  • 普通字符 包括大小写字母、数字、标点符号及一些其他符号。
  • 元字符 是指在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符或表达式)在目标对象中的出现模式。

LINUX 中文本处理工具:grep、egrep、sed、awk

元字符含义
\*转义字符,用于取消特殊符号的含义,例:\!、\n、\s等
\匹配字符串开始的位置,例:^ a、^ the、^ #、^ [a-z]
$匹配字符串结束的位置,例:word、^ 匹配空行
.匹配除\n之外的任意的一个字符,有且仅有一个。例:go.d、g…d
*匹配前面子表达式0次或者多次,例:goo*dgo.*d
[list]匹配list列表中的一个字符,例:go[ola]d,[abc]、[a-z]、[a-z0-9]
[^list]匹配任意非list列表中的一个字符,例:[ ^A-Z0-9],[ ^a-z]匹配任意一位非小写字母
[[:alpha:]]代表任意一个大小写英文字母,相当于[A-Za-z]
[:[:digit:]]代表任意一个十进制数字,相当于[0-9]
[[:alnum:]]代表任意一个大小写英文字母及数字,相当于[A-Za-z0-9]
\ {n\ }匹配前面的子表达式n次,例:go{2}d、 '[0-9]{2}'匹配两位数字
\ {n,\ }匹配前面的子表达式不少于n次,例:go{2,}d'[0-9]{2,}'匹配两位及两位以上数字
\ {n,m\ }匹配前面的子表达式n到m次,例:go{2,3}d'[0-9]{2,3}'匹配两位到三位数字

注: egrep、 awk使用{n}、{n,}、{n, m}匹配时 "{ }" 前不用加" \ "

定位符
^ 匹配输入字符串开始的位置
$ 匹配输入字符串结尾的位置
 
非打印字符
\n 匹配一个换行符
\r 匹配一个回车符
\t 匹配一个制表符

正则表达式元字符

支持的工具:egrep、awk 或 grep -E 和 sed -r

元字符含义
+匹配前面子表达式1次及以上,例: go+d,将匹配至少一个o,如god、good、 goood等
匹配前面子表达式0次或者1次,例: go?d,将匹配gd或god
( )将括号中的字符串作为一个整体,例1: g(0o)+d,将匹配oo整体1次以上,如good、gooood等
l以"或"的方式匹配字符串

+:匹配前面的子表达式1次及以上(至少1次)。

[root@localhost ~]# egrep "go+d" 2.txt
god
good
gooood

?:匹配前面子表达式0次或者1次

[root@localhost ~]# egrep "go?d" 2.txt
god

( ):将括号中的字符串作为一个整体

[root@localhost ~]# egrep "g(oo)+d" 2.txt  //至少匹配一次oo
good
gooood

|:以"或"的方式匹配字符串。

[root@localhost ~]# egrep "g(oo|ol)d" 2.txt //表示oo 或者 ol
good
gold


[root@localhost ~]# egrep "go(o|a)d" 2.txt  //表示o或者a
good
goad

两个案例

匹配电话号码

  1. 匹配 025 开头的区号。

  2. 电话号码要5 或者 8开头的八位数。

  3. 格式如下:

 区号 号码
 区号-号码
 区号号码
 123
 [root@localhost sh]# cat 99.txt
 02588888888          //符合
 025-5555555555      
 025 12345678
 025 54321678         //符合
 025ABC88888
 025-85432109         //符合
 0251-85432109
 0025-85432109
 [root@localhost sh]# egrep "^(025)[- ]?[58][0-9]{7}$" 99.txt
 02588888888
 025 54321678
 025-85432109
 
 "^(025)  //区号以025开头
 [- ]?  //-或空格 出现0次或者1次
 [58]   //电话号码以5或者8开头
 [0-9]  //电话号码的数字范围
 {7}$"   //因为前面的5或者8已经涨了一位,所有这里是7位$是结束符
 

用户名@子域名.[二级域名].顶级域

  1. 用户名:长度要求在6-18位,任意大小写英文,任意数字,除了@符号和空格以外的其它任意符号字符,开头只能是 _ 或者字母。
  2. 子域名.[二级域名]:长度任意,符号只能包含 - _ .
  3. .顶级域名:长度在2-5,任意大小写英文。
  4. 完整匹配。
 用户名长度要求在6-18位    {6,18}
 除了@符号和空格以外的其它任意符号字符    [^@ ]
 开头只能是 _ 或者字母       ^[a-zA-Z_]
 ​
 长度任意,符号只能包含-_.    [a-zA-Z0-9-_.]+
 ​
 长度在2-5,任意大小写英文    \.[a-zA-Z]{2,5}
 [root@localhost ~]# cat mh.txt
 zhangsan123@qq.com
 li_si@163.com
 wang@wu@sina.com
 zhao liu@126.com
 qianqi@sina.com.cn
 [root@localhost ~]# egrep "(^[a-zA-Z_][^@ ]{5,17})@([a-zA-Z0-9-_.]+).[a-zA-Z]{2,5}$" hm.txt
 zhangsan123@qq.com
 qianqi@sina.com.cn

常见的管道命令

sort命令

以行为单位对文件内容进行排序,也可以根据不同的数据类型来排序

比较原则是从首字符向后,一次按ASCII码值进行比较,最后将他们按升序输出

语法格式:

sort [选项] 参数

cat file | sort 选项

常用选项

选项含义
-n按照数字进行排序
-r反向排序
-u等同于uniq,表示相同的数据仅显示一行
-t指定字段分隔符,默认使用[Tab]键分割
-k指定排序字段
-o<输出文件>:将排序后的结果转存至指定文件
-f忽略大小写,会将小写字母都转为大写字母进行比较
-b忽略每行前面的空格
-n按照数字进行排序
[root@localhost mm]# sort 1 -n
1
5
6
9
55
77
222
333
888
4444
-r反向排序
[root@localhost mm]# sort 1 -r
9
888
77
6
55
5
4444
333
222
1
-u等同于uniq,表示相同的数据仅显示一行
[root@localhost mm]# sort 1 -u
1
222
333
4444
5
55
6
77
888
9
-t指定字段分隔符,默认使用[Tab]键分割
[root@localhost mm]# cat 2 -t
aaa
b
c
ddd
rrrrr
rr
t
i
ppp
ewq
ges
zr
-k指定排序字段
[root@localhost mm]# sort -n -t ':' -k3 /etc/passwd
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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
-o<输出文件>:将排序后的结果转存至指定文件
[root@localhost mm]# sort -n -t ':' -k3 /etc/passwd -o passwd.txt
[root@localhost mm]# ls
1  2  passwd.txt
[root@localhost mm]# cat passwd.txt
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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
-f忽略大小写,会将小写字母都转为大写字母进行比较
[root@localhost mm]# sort -f 2
aaa
b
c
ddd
ewq
FOE
ges
i
OEW
ppp
rr
rrrrr
t
zr
-b忽略每行前面的空格
[root@localhost mm]# sort 2 -b
aaa
b
c
ddd
ewq
FOE
ges
i
   OEW
ppp
     rr
rrrrr
t
zr

当前目录下最大的子目录查找

[root@localhost mm]# du -d 1 /var | sort -nr
181876  /var
117296  /var/lib
52408   /var/cache
12124   /var/log
20      /var/spool
12      /var/tmp
8       /var/db
0       /var/yp
0       /var/www
0       /var/target
0       /var/preserve
0       /var/opt
0       /var/nis
0       /var/local
0       /var/kerberos
0       /var/gopher
0       /var/games
0       /var/empty
0       /var/crash
0       /var/adm
0       /var/account

uniq命令

uniq 命令用于检查及删除文本文件中重复出现的行列,一般与 sort 命令结合使用

格式:uniq [选项] 参数
cat file | uniq 选项

常用的选项

选项说明
-c进行计算,并删除文件中重复出现的行
-d仅显示连续的重复行
-u仅显示出现一次的行

uniq不加选项,只会对连续的重复行进行去重。

 [root@localhost ~]# cat 2.txt
 1
 2
 33
 33
 33
 444
 444
 1
 33
 2
 444
 [root@localhost ~]# uniq 2.txt
 1
 2
 33
 444
 1
 33
 2
 444

uniq -c,显示连续重复行出现的次数,并合并重复行。

 [root@localhost ~]# uniq -c 2.txt
       1 1
       1 2
       3 33
       2 444
       1 1
       1 33
       1 2
       1 444

tr命令

常用来对来自标准输入的字符进行替换、压缩和删除。

 cat file | tr [选项]  参数

常用选项

选项说明
-c保留字符集1的字符,其他的字符用(包括换行符\n)字符集2替换
-d删除所有属于字符集1的字符
-s将重复出现的字符压缩为一个字符串:用字符集2替换字符集1
-t字符集2替换字符集1,不加选项同结果

字符集1,字符集2

参数说明
字符集1指定要转换或删除的原字符集。当执行转换操作时,必须使用参数"字符集2"指定转换的目标字符集。但执行删除操作时,不需要参数"字符集2”
字符集2指定要转换成的目标字符集
 [root@localhost ~]# echo abc | tr 'a-z' 'A-Z'     //将所有小写字母替换为大写
 ABC
 [root@localhost ~]# echo abc | tr 'a' 'A'         //将小写a替换为大写A
 Abc
 [root@localhost ~]# echo abc | tr -t 'a' 'A'      //将小写a替换为大写A
 Abc
 [root@localhost ~]# echo "192.168.80.10" | tr '.' ' '    //将.替换为空格
 192 168 80 10

cut命令

显示行中的指定部分,删除文件中指定字段

格式:cut [选项] 参数

常用选项

选项说明
-f通过指定哪—个字段进行提取。cut命令使用“TAB"作为默认的字段分割符
-d“TAB”是默认的分隔符,使用此选项可更改为其他的分隔符
--complement用于排除所指定的字段
--output-delimiter更改输出内容的分隔符

-d 指定分隔符,-f 按字段进行截取 #####** plit命令** split命令用于在Linux下将大文件拆分为若干小文件。

 split 选项 参数 原始文件 拆分后文件名前缀

常用选项:

选项说明
-l指定行数
-b指定大小
eval命令

命令字前加上eval,shell会在执行命令之前扫描它两次,eval命令首先会先扫描命令行进行所有的置换,然后再执行命令,该命令适用于那些一次扫描无法实现功能的变量,该命令会对变量进行两次扫描。

 [root@localhost ~]# echo "hello world">file
 [root@localhost ~]# cat file
 hello world
 [root@localhost ~]# myfile="cat file"
 [root@localhost ~]# echo $myfile     //输出变量myfile的值
 cat file
 [root@localhosti ~]# eval $myfile    //扫描命令2次,先将myfile置换成"cat file",之后执行"cat file"
 hello world