Linux进阶之正则,shell三剑客(grep,awk,sed),cut,sort,uniq

一、正则表达式:Regular Expression

正则表达式:正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

作用:用一些特殊的字符来描述一个模式

正则是用于对文件中的内容进行过滤和匹配

通配符用于对文件名进行匹配

注意:在匹配模式中一定要加上引号

二、符号:

^           以开头

$           以结尾

^12$     1开头以2结尾

^$         空行

.     表示任意的一位字符(数字、字母、符号)

+    表示其前面的字符至少重复一次,可以是无数次

?    表示其前面的字符出现最多一次的情况,可以是0

*    重复任意次数(包括0次)

.*   表示任意长度的任意字符

{} 

{数字} 重复数字次,准确的重复多少次

{数字1,数字2}    至少重复数字1次,最多重复数字2

{数字,}           至少重复数字次,最多不限

{,数字}           最多重复数字次,最少不限

[]    表示范围,多个范围使用 , 分隔

[^字符]        表示匹配[^字符]之外的任意一个字符

^[^]       匹配不是中括号内任意一个字符开头的行

[0-9]            表示1位数字(0-9任意数字)

[a-z]             表示1位小写字母

[A-Z]    表示1位大写字母

[0-9,a-z,A-Z]

()           表示内部是一个整体

|            表示或者

三、常用的正则表达式

1、车牌号码

^[A-Z][0-9,A-Z]{5}$

2、手机号码

^1[0-9]{10}$

3、身份证号

^[0-9]{17}[0-9,X]$

4IP0-255.0-255.0-255.0-255

0-9 [0-9]

10-99    [1-9][0-9]

100-199       1[0-9][0-9]

200-249       2[0-4][0-9]

250-255       25[0-5]

方法一:^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$

方法二:^([0-9]\.|[1-9][0-9]\.|1[0-9][0-9]\.|2[0-4][0-9]\.|25[0-5]\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$

5、密码(8位以上,包含数字、大小写字母)

egrep [a-z] passwd | egrep [A-Z] | egrep [0-9] | egrep ^.{8,}$

四、grep

作用:用于对文件中的内容进行过滤

原理:逐行对文件中的内容根据样式进行匹配,如果匹配成功就过滤出该行

格式:grep [options] PATTERN file

PATTERN:要匹配的模式

参数:

-e   =正则 用正则表达式来进行匹配操作,egrep=grep -E(extended-regexp)grep调用正则表达式

-f =文件 从文件中取得条件

-i    (--ignore-case)忽略文件中内容的大小写

-n   (--line-number)打印包含匹配项的行和行号

-o   (--only-matching)只输出匹配的选项(不显示整行)

-w 完全匹配字词(精确匹配)

-x   仅完全匹配一行

-c   (--count)只打印每个文件匹配的行数

-v   (--invert-match)取反,打印不匹配的行

-V 显示版本信息

--color   将匹配到的内容进行着色

--help 显示帮助

-B NUM     (--before-context=NUM) 显示匹配到的条件的之前 数字

-A NUM     (--sfter-context=NUM) 显示匹配到的条件的之后 数字

-C NUM      (--context=NUM)显示匹配到的条件的为中心上下 数字

-NUM 等于-C

例子:

1、显示出test中不包含字母c的行

[root@ren4 ~]# grep -v "c" test

2、统计test中包含字母a的行的数量

[root@ren4 ~]# grep "a" test | wc -l

3、过滤出包含大写字母的行

[root@ren4 ~]# grep '[A-Z]' test

4、匹配非数字字符

[root@ren4 ~]# grep '[^0-9]' test

5、查看包含字母a的行,要求显示该行上下各2

[root@ren4 ~]# grep --color -C 2 'a' test

6、过滤出一行中a在前,v在后的行

[root@ren4 ~]# grep --color 'a.*v' test

7、匹配ab之间有最少2c最多5c的行

      [root@ren4 ~]# grep "ac\{2,5\}b" test

accccb

[root@ren4 ~]# egrep "ac{2,5}b" test

accccb

8过滤出以#为开头,且第二个字符是空格的行

[root@ren4 ~]# grep "^#[[:space:]]" test

[root@ren4 ~]# grep "^#[:space:]" test         #语法错误

grep: 字符类的语法是 [[:space:]],而非 [:space:]

9过滤出行首和行尾字母相同的行

[root@ren4 ~]# grep "^\([a-z]\).*\1$" test

adfdfa

[root@ren4 ~]# egrep "^([a-z]).*\1$" test

adfdfa

10、过滤出第一个字符是#,且第二个字符串是非空字符,而且结尾是数字的行

      [root@ren4 ~]# grep --color "^#[^[:space:]].*[0-9]$" test

正则练习

使用文件 /etc/init.d/functions ,下面可能有些部分题目匹配不到符合的情况。

1. 过滤出包含大写字母的行

[root@ren4 ~]# egrep "[A-Z]" /etc/init.d/functions

2. 匹配非数字字符

[root@ren4 ~]# egrep "[^0-9]" /etc/init.d/functions

3. 过滤出一行中a在前,b在后的行

[root@ren4 ~]# egrep "a.*b" /etc/init.d/functions

4. 匹配ab之间有最少2c最多5c的行

[root@ren4 ~]# egrep "ac{2,5]b" /etc/init.d/functions

5. 过滤出一行包含相同数字的行/etc/init.d/functions

[root@ren4 ~]# egrep ".*([0-9]).*\1" /etc/init.d/functions

6. 过滤出不是(空行和以#开头)的行

[root@ren5 ~]# egrep -v "(^#)|(^$)" test

五、awk

1、功能:逐行处理文件中的内容(读取一行,处理一行)

2、语法:

awk [options] '[pattern]{action}' fileName

options:选项,比如 -F 指定分隔符

pattern:输出的条件,比如仅仅输出以#开头的行

action:按照选项切换,并且是符合条件的行,要执行的操作或者命令,比如输出

awk -F分隔符号 '{print $列数}' #-F可以不写,默认使用空格分隔

awk -F分隔符 '{print $列数}' 文件名 #可以直接过滤文件,但不会对源文件内容进行更改

#列说明 $0所有列 $数字 第数字列

3、概念及参数

记录(record):一行就是一个记录

分隔符(field separator):进行对记录进行切割的时候所使用的字符

字段(field):将一条记录分割成的每一段

FILENAME:当前处理文件的文件名

FSField Separator):字段分隔符(默认是以空格为分隔符=

NRNumber of Rrecord):记录的编号(awk每读取一行,NR就加1==

NFNumber of Field):字段数量(记录了当前这条记录包含多少个字段==

ORSOutput Record Separator):指定输出记录分隔符(指定在输出结果中记录末尾是什么,默认是\n,也就是换行)

OFSOutput Field Separator):输出字段分隔符

RS:记录分隔符

4、示例:

1. awk 打印所有包含有 root 字段的行

[root@ren5 ~]# awk '/root/' /etc/passwd

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

2.查看 df -h 命令的第 2

[root@ren5 ~]# df -h |awk '{print $2}'

3. 查看 df -h 命令的第 2,5

[root@ren5 ~]# df -h |awk '{print $2,$5}'

4.显示 passwd 的第四行

[root@ren5 ~]# awk 'NR==4' /etc/passwd  #必须是两个等号

5.打印 ls l / 中包含 etc字段行的第二区域

[root@ren5 ~]# ls -l / |awk '/etc/ {print $2}'

6.列示月份及年份 (\n 为换行符 )

[root@ren5 ~]# date |awk '{print $1,$2}'

2019 08

[root@ren5 ~]# date |awk '{print "Year:"$1"\nMonth:"$2}'

Year:2019

Month:08

7.在有 root 关键字的行的第 1 列后面增加 1 \t制表符,并增

RedHat,第 2 列后面加 ! 字符

awk -F: '/root/{print $1 "\tRedHat" $2 "!"}' /etc/passwd

8.在有 root字段的行前增加记录号 ($0 为行头前 )

[root@ren5 ~]# awk -F: '/root/{print NR,$0}' /etc/passwd

1 root:x:0:0:root:/root:/bin/bash

10 operator:x:11:0:operator:/root:/sbin/nologin

[root@ren5 ~]# awk -F: '/root/{print $0}' /etc/passwd

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

9.以:分割,匹配第一列的 root字段,如果有,则显示整行

[root@ren5 ~]# awk -F ":" '$1 ~/root/' /etc/passwd

10.以:分割,匹配第一列不存在 root字段的行,如果有,则显

示行号和第一列

[root@ren5 ~]# awk -F ":" '$1 !~/root/{print NR,$1}' /etc/passwd

11. 在结果前打印 hello,可以是任何的字符

[root@ren5 ~]# awk 'BEGIN{print "Hello"}{print $0}' /etc/passwd

12. 在结果后打印 hello,可以是任何的字符

[root@ren5 ~]# awk 'END{print "Hello"}{print $0}' /etc/passwd

13.使用awk进行计算 + - * / 可以带()^开方

[root@ren5 ~]# awk 'BEGIN{print 2+1}' /etc/passwd

14.比较 >大于 <小于 >=大于等于 <=小于等于 ==等于

[root@ren5 ~]# awk -F ':' '$3<=88{print $1,$3}' /etc/passwd

#如果第三列小于等于88,输出第一列和第三列

六、sed

1、概念:文本编辑器,也是对文件中的内容进行逐行的处理(一次处理一行)

2、功能:通过指定的正则表达式完成指定关键字的过滤、截取、修改等操作

3sed的工作原理:

sed读取一行,首先将这行放入到缓存中

然后,才对这行进行处理

处理完成以后,将缓冲区的内容发送到终端

存储sed读取到的内容的缓存区空间称之为:模式空间(Pattern Space

4、语法格式: sed ‘command’ filename(s)

5、特点:

1.sed属于一个流线式的非交互式的编辑器

2. sed在输入命令和文件名后,将在屏幕上输出

3.在不用重定向至文件之前,是不会改变文件现有内容。以避免修改文件时出现问题

6、选项:

Option选项

解释说明

-nno

取消默认的sed软件的输出,常与sed命令的p连用。(抑制内存输出)

-eentry

一行命令语句可以执行多条sed命令

-rregular

使用扩展正则表达式,默认情况sed只识别基本正则表达式

-iinside

直接修改文件内容,而不是输出到终端,如果不使用-i选项sed软件只是修改在内存中的数据,并不会影响磁盘上的文件

pprint

打印模式空间内容,通常p会与选项-n一起使用

aappend

追加,在指定行后添加一行或多行文本

iinsert

插入,在指定行前添加一行或多行文本

ddelete

删除指定的行

cchange

取代指定的行

ssubstitute

字符串替换

rread

从一个文件中读取到另一个文件中

wwrite

从一个文件中将匹配的内容写入到另外一个文件中

&

引用前面的搜索结果

!

对指定行以外的所有行应用命令,对命令的执行结果取反(不显示命令找到的内容)

6、示例:

1)查找指定的字符串

[root@ren5 ~]# sed -n '/root/p' /etc/passwd       #显示有/root/的行

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

[root@ren5 ~]# sed -n '2,5p' /etc/passwd           #显示25

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@ren5 ~]# sed -n '2p' /etc/passwd       #显示第2 行的内容,如果不加-n,是显示所有内容,但第二行有2行。

2)删除

[root@ren5 ~]# sed 'd' test     #删除所有test内的内容

[root@ren5 ~]# sed '2d' test   #删除第2

[root@ren5 ~]# sed '2,5d' test       #删除第25

[root@ren5 ~]# sed '/ren/d' test     #删除包含ren的行

[root@ren5 ~]# sed '2,$d' test       #删除第2行到行尾的内容(包含第2行)

[root@ren5 ~]# sed '2,6!d' test      #取反删除)除了第2行到第6行,其它都删除

[root@ren5 ~]# sed '/ren/!d' test   #删除不包含ren的所有行

3)增加内容

[root@ren5 ~]# sed "2a 你好" test            #在第2行后增加内容

this is the first line

this is the second line

你好

this is the third line

this is the forth line

[root@ren5 ~]# sed "2i 你好" test             #在第2行前增加内容

this is the first line

你好

this is the second line

this is the third line

[root@ren5 ~]# sed "i 你好" test        #在每一行的前面增加

[root@ren5 ~]# sed "2,5i 你好" test          #2-5行前面增加

[root@ren5 ~]# sed "2i 你好\n我很好" test           #换行(增加多行内容)

this is the first line

你好

我很好

this is the second line

[root@ren5 ~]# sed "2i 你好\n\t\t我很好" test      #换行+tab+tab

this is the first line

你好

            我很好

this is the second line

4)修改,替换

[root@ren5 ~]# sed '2c 改过之后的第二行' test           #整行替换

this is the first line

改过之后的第二行

this is the third line

[root@ren5 ~]# sed 's/is/ese/' test        #默认替换每一行的第一个

these is the first line

[root@ren5 ~]# sed 's/is/ese/g' test             #全文替换

these ese the first line

[root@ren5 ~]# sed 'y/e/E/' test           #字母替换,默认替换所有适配字母

this is thE first line

[root@ren5 ~]# sed -i 's/t/T/' test         #修改磁盘文件

[root@ren5 ~]# cat test

This is the first line

[root@ren5 ~]# sed 's/is/are/2' test       #指定替换每行的第2个词

This are the first line

[root@ren5 ~]# sed 's/is/are/2w test2' test         #将修改后的文本保存至test2

5)多点编辑(-e

[root@ren5 ~]# sed -e '2d' -e '4d' test         #删除第2行和第4

This is the first line

This is the third line

This is the fivth line

[root@ren5 ~]# sed -n -e '3p' -e '7p' test     #显示第3行和点7

This is the third line

This is the seventh line

[root@ren5 ~]# sed -e '/^#/d' -e '/^$/d' test        #删除文件中的注释行和空白行

七、其它小命令(cutsortuniq

1cut命令

作用:根据指定的分隔符来切割数据,然后显示指定的部分

选项:

-d ’字符:(--delimiter=分界符)指定分隔符

-f #:(--fields=LIST)指定显示分割后的那一部分数据,取第几位的字符(#代表数字)

     输出的情况

     1)输出一段:指定一个编号   2

     2)输出连续多段:编号-编号 2-5

     3)输出不连续多段:编号,编号... 2,3,5

示例:

1bin:10:15:i am bin:/home/bin:/sbin/nologin

#输出上面的15

[root@ren5 ~]# echo "bin:10:15:i am bin:/home/bin:/sbin/nologin" |cut -d ':' -f3

15

2#输出系统中全部用户的用户名和shell类型

[root@ren5 ~]# cat /etc/passwd |cut -d":" -f1,7

root:/bin/bash

2sort命令

作用:按字符进行比较和排序,默认以排序 ASCII 方式进行排序 [a-z]

格式:sort 选项 file

选项:

-t:( --field-separator=分隔符)指定分隔符

    -k:(--key=KEYDEF)根据切割后的那一段进行排序(根据切割后的那一段排序,不是取出来那一段)

   -n:(--numeric-sort)表示根据数字进行排序(默认是根据字符进行排序)

    -f:(--ignore-case)忽略要比较的字符大小写

 -c, --check, --check=diagnose-first      检查输入是否已排序,若已有序则不进行操作

    -u:(--unique)去除重复的行(只要那个指定的字段重复,就认定是重复的行)配合-c,严格校验排序;不配合-c,则只输出一次排序

    -r:(--reverse)按照降序(逆序)排序[z-a]

示例:

1)对 /etc/passwd 文件进行升序排序

[root@ren5 ~]# sort /etc/passwd

2)对 /etc/passwd 文件进行降序排序

[root@ren5 ~]# sort -r /etc/passwd

3)对 /etc/passwd 3列进行数值排序,分界符为:

[root@ren5 ~]# sort -n -k 3 -t : /etc/passwd

4)对第 1 列的第2个字符开始至本列最后1个字符排序

[root@ren5 ~]# sort -k 1.2 -t : /etc/passwd        #注意1.2中间是小数点

3uniq命令

uniq命令(通常结合sort先进行排序,然后再使用该命令统计相同的行出现的次数)

作用:去除重复的行(相邻且相同,认定为重复)

选项:

     -c:(--count)在行首用数字表示该行出现了多少次

     -d:(--repeated)仅仅显示出现过重复的行

     -u:(--unique)仅仅显示那些没有出现重复过的行

例子:uniq用法

[root@ren5 ~]# uniq -c test

      2 This is the first line

      1 This is the third line

[root@ren5 ~]# uniq -d test

This is the first line

[root@ren5 ~]# uniq -u test

This is the third line

This is the forth line

[root@ren5 ~]# uniq test

posted @ 2019-07-29 20:39  Wolf_Coder  阅读(1244)  评论(0编辑  收藏  举报