shell-正则表达式与文本三剑客grep、sed、awk

一、概念

正则表达式:

对文件内容进行增删改查

linux的文本三剑客:都是针对文本内容修改

grep:过滤(查找文本内容--借助正则表达式一块使用)查

sed:改

awk :对行来进行取列,awk自带编程,类Java格式

以上都是针对文件内容来进行处理的

二、相关命令
1、grep:过滤

都是按行处理的

grep 最主要的作用之一就是方便对日志内容过滤。

基本格式:

grep -n “root” /etc/passwd

cat /etc/passwd | grep -n “root” 

grep -v:取反

grep -m:对个匹配,只取第一个。m后面要加数字,可以自定义

grep -n:显示匹配内容以及对应行号

grep -o:仅显示匹配到的字符串,不再输出其他内容

grep -A:after 表示后几行。-A后要接数字,表示过滤出来的行以及匹配到的行的后几行,数字自定义

grep -B:before 前几行,显示匹配到的行以及他的前几行,数字自定义

grep -C:前后各几行,显示匹配到的行以及他的上下机几行,数字可以自定义

grep -e:逻辑“或”,多个逻辑关系

grep -E:使用正则表达式

grep -f:过滤出两个文件的相同内容

grep -r:递归目录下,所有包含过滤内容的文件以及匹配的内容行,但是不处理软连接

grep -R:递归目录下,所有包含过滤内容的文件以及匹配的内容行,但是他处理软连接

2、sort:排序

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

格式:

sort 选项 参数

cat /etc/passwd | sort 选项

常用选项:

sort -b:忽略每行前面的空格,进行排序,有空格也不影响排序

sort -n:按照数字进行排序(实验结果貌似和-b一样)

sort -r:反向排序按照数字排序

sort -u:去重,相同的数据行只显示一行

sort -o:指定输出文件,把排序后的结果,输出到指定的内容文件


 

3、uniq:快捷去重

报告或者忽略文件中连续的重复行,常与sort命令结合使用

而sort -nu 是不连续的重复都去重

格式:

uniq 选项 参数

cat 文件 | uniq 选项

常用选项:

uniq -c:统计连续重复的行的次数,合并重复的行

uniq -u:显示仅出现一次的行(包括不连续的重复行

uniq -d:仅显示重复出现的行(必须是连续的重复行

和sort合用的时候 要注意先后顺序管道符前的先执行 执行完的结果在操作

4、tr:替换、压缩、删除

对字符进行替换、压缩、删除

格式:

tr 选项 参数

echo 123: | tr 选项

常用选项:

tr -c:保留字符集1的字符,其他字符用字符集2来进行替换。输出结果会默认多打一个字符

tr -d:删除字符

tr -s:将重复出现的字符串压缩为一个字符。也可以替换字符集

替换:

tr -t:替换

5、cut:按列截取

对字段进行截取和剪裁

格式:

cut 选项 参数

cat 文件名 | cut 选项

常用选项:

cut -d:指定分隔符吗,截取字段

cut -f:对字段进行截取

cut -d ‘:’ -f 1-3 /etc/passwd

以冒号为分隔符,截取1-3列

cut -d ‘:’ -f 1,3 /etc/passwd

以冒号为分隔符,截取第1列和第3列

cut -b:以字节为单位截取

cut -c:以字符为单位截取

cut -complement:排除所指定的字段

 cat /opt/test/11.txt | cut -d "/" --complement -f 1-3

除了指定列,都截取出来

cut --output-delimiter:更改原内容的分隔符

cut和awk有相似之处:

都是对行来取列

cut的默认分隔符是tab键

awk的默认分隔符就是空格,把对个连续的空格当做一个处理

cut主要用来切文本,指定分隔符最好是指向性越强越好(功能没有awk强)

对文件进行分割和合并:

6、split:文件拆分

可以把文件拆分成若干个小文件

split -l:指定行数进行拆分

split -b:指定文件大小进行拆分

7、paste 、cat:文件合并

面试题:合并文件,paste和cat之间的区别

paste 左右合并

paste 11.txt 22.txt >> 33.txt

cat 上下合并

cat 11.txt 22.txt >> 33.txt

他两合并之后要输出才能保存

8、解决实际问题

1、 怎么把原文件按照原来不变的顺序排序:

怎样不改变原文件的顺序,输出到;另外一个文件中:

cat -n /etc/passwd | sort -n -o /opt/xxx.txt

先cat -n 显示原文件行号

在利用管道符 和 sort -n -o 根据行号进行排序输出

---------------------------------------------------------------------------------------------------------------------------------

2、现在有一个日志文件——nginx——nginx.log——有5G——文件太大打开太慢

你有什么方法可以提高这个文件的打开速度

答案:用split命令对文件进行拆分

---------------------------------------------------------------------------------------------------------------------------------

3、如何统计当前主机的连接状态:有多少个LISTEN 有多少个 ESTAB

答:

1、先将需要的信息过滤出来

2、再将过滤出来的信息,进行排序,以便于下边uniq -c 统计连续重复的次数

3、用uniq -c压缩连续重复并且计数

ss -nta | grep -v State | cut -d   -f 1 | sort | uniq -c

先将需要的信息提取出来:

ss -nta | grep -v State | cut -d   -f 1

在把相同的元素排序:sort

最后在统计:uniq -c

若要cut取中间有空格的:

先tr -s       将空格压缩成一个空格

---------------------------------------------------------------------------------------------------------------------------------

三、正则表达式:

匹配文件内容。根据特定的字符和表达式

在linux下配合:

命令:grep、sed、awk

进程:nginx、mysql匹配文件也可以支持正则表达式

通配符和正则表达式的区别:

通配符匹配的是文件名称:

只能匹配文件名,根文件内容没有关系。正则表达式可以匹配文件内容

*:匹配任意一个或者多个字符

?:匹配任意1个字符

??:匹配任意2个字符

正则表达式:

注意:

使用正则表达式,一定要把匹配内容引起来

1、元字符:

.    匹配任意单个字符,可以是一个汉字(相当于通配符中的*)

\  转义符

()   使用转义符,只表示\(\)

[]   匹配指定范围内的任意单个字符,示例:[dn]   [0-9]   []   [a-zA-Z]   [:alpha:]

[^]  匹配指定范围外的任意单个字符,示例:[^dn] [^a.z]

[:alnum:] 字母和数字 [0-9] [a-z] [0-9] [a-z]

[:alpha:] 代表任何英文大小写字符,亦即 [A-Z], [a-z]

[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]

[:upper:] 大写字母 [A-Z]

[[:blank:]] 空白字符(空格和制表符)

[:space:] 包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广

[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)

[:digit:] 十进制数字

[:xdigit:]十六进制数字

[:graph:] 可打印的非空白字符

[:print:] 可打印字符

[:punct:] 标点符号

\w #匹配单词构成部分,等价于[_[:alnum:]]

\W #匹配非单词构成部分,等价于[^_[:alnum:]]

\S #匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。

\s #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。

[] 中只匹配单个字符:

表示次数

*   #匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配 >=0

.* #任意长度的任意字符,不包括0次,也就是匹配所有 >0

\? #匹配其前面的字符出现0次或1次,即:可有可无,有且只有一次 0或者1次

\+ #匹配其前面的字符出现最少1次,即:肯定有且 >=1 次

\{n\}    #匹配前面的字符=n次  精准匹配n次,不然匹配不了

\{m,n\} #匹配前面的字符至少m次,至多n次

\{,n\} #匹配前面的字符至多n次,<=n,没有也算

\{n,\}   #匹配前面的字符至少n次,只要连续出现n次后面的都算

以上匹配都是连续出现的重复

用正则表达式的方式将ifconfig 的 IP地址 子网掩码 匹配出来

grep -o 只展示匹配结果

先过滤数字,在过滤格式。

位置锚定:

^:行首锚定,以什么为开头(grep “^root”)

$:行尾锚定,以什么为结尾(grep “bash$”)

grep “^root$”  单独一行,匹配只有root的一行

grep “^$”   匹配空白行

grep ‘^[^#]’  匹配非#开头的行

^[[:space:]]*$  也是空白行

\< 或者 \b   表示词首锚定,一般用于匹配单词模式的左侧

从左往右全部都算。所有一起都包含,所有都能匹配到

\> 或者 \b   表示词尾锚定,一般用于匹配单词模式的右侧

从右往左,只匹配右侧的单词,只能匹配一般单词,左侧的单词不匹配

\broot\b:匹配整个单词root

\<root\>:也是匹配整个单词root

分组以及逻辑或:

()  表示分组

\|  表示逻辑或

扩展正则表达式:用grep -E(把斜杠都丢掉)

必须用grep -E 或者 egrep 使用扩展正则表达式

grep -E 扩展正则表达式

*:匹配前面的字符任意次,包括0次,尽可能长的匹配

.*: 匹配前面的字符任意次,但是不包括0次。也就是匹配所有。

?: 匹配前面的字符出现0次,或者1次,有且只有一次。

+:匹配前面出现的字符,至少出现一次,也就是>=1,

{n }:匹配前面出现的字符等于几次。

{m,n }:匹配前面出现的字符最少M次,最多是n次

{ ,n } : 匹配前面的字符最多N次,没有也算。

{ n, }: 匹配前面的字符最少N次,只要连续出现N次,后面的都算。

|:表示逻辑或

grep -E

egrep

扩展正则表达式这两个都可以

练习:

1、

025-83346023

0512-88776655

021-88998877

 grep -E '[0-9]{3,4}-[0-9]{8}'

2、

544564317@qq.com

CICIfireway@126.com

aaabbbccc@189.cn

 grep -E '[0-9a-zA-Z]+@[0-9a-z]+\.[a-z]+'

3、

66606@qq.com

544677766@qq.com

544564317@qq.com

5555555555@qq.com

grep -E '[0-9]+@[q]{2}\.[com]+'

4、终极

987-123-4567

987 456-1230

(123) 456-7890

cat 11.txt | grep -E "^(\([0-9]+\)|[0-9]+)[ -]?[0-9]+-[0-9]+"

cat 11.txt | grep -E '\([0-9]+\)|[0-9]+[ -]?[0-9]+-[0-9]+'

sed编辑器:

文本三剑客:grep、sed、awk

sed:行编辑器

sed也是按行来处理

sed是一种流编辑器,每一次处理内容,只有确认才会生效,不确认的,只是把模式空间的临时数据展示给用户,然后删除。

按照文本的行,一行一行向下处理,直到文件的最后一行。

默认情况下:sed命令都是在模式空间执行,因此原文件不会发生变化。

若要变化怎么办呢?

展开学习:

sed的操作格式:

sed -e:指定命令来处理输入的文本文件

只有一个操作 -e可以省略——多个指令要用-e

格式:

sed -e  “操作” 文件1 文件2

sed -e  “操作1;操作2” 文件1 文件2

常用选项:

sed -f:用特定的脚本文件来处理输入的文件

sed -i:立即生效,慎用

sed -n:仅显示处理之后的结果

sed的操作符:

=:只打印行号

p:打印

d:删除

 sed 'p' 11.txt

sed自己还有一个默认输出,又使用-p打印,所以打印两遍

sed -n ‘p’ 11.txt   仅显示处理后的结果。只打印结果

sed -n '2p' 11.txt  只打印第二行

sed -n '$p' 11.txt    $p 只打印最后一行

sed -n '1,3p' 11.txt   打印第1行到第3行 1-3

sed -n '1p;3p' 11.txt   打印第1行和第3行

sed -n '1p;$p' 11.txt    打印第1和最后一行

sed -n -e'1p' -e'$p' 11.txt    打印第1和最后一行

sed -n "=" 11.txt   只显示行号不显示内容

sed -n "=;p" 11.txt

sed -n 'n;p' 11.txt   打印偶数行

把n看做跳一行

n在p前面,跳过当前一行,打印下一行

sed -n 'p;n' 11.txt  打印奇数行

p在n前面,打印当前一行,跳过下一行继续打印

文本模式:

文本内容过滤:

打印指定的过滤内容:

sed -n '/要过滤的内容/p' 11.txt

打印t开头o结尾的行:

sed -n '/^t.o$/p' test.txt

打印t开头或者o结尾的行

sed -rn '/^t|o$/p' test.txt

练习:

从第四行开始,一致打印到第一个以bash为结尾的所在行为止(从第4行到目的行中间的全部)

sed -n '4,/bash$/p' /etc/passwd

sed使用扩展正则表达式:sed -r

sed -r 表示可以使用扩展正则表达式。(在使用{n},{n,},{,n},{n,m} 都不需要加/)

要求包含有两个99:的所在行,打印出来

打印所有要么是以root开头 要么是以bash结尾的行

sed删除文件内容:

sed -i ‘d’  删除文本内容

现在有一个文件,文件名我想保留,但是原有的内容我想删除掉

要免交互删除

免交互清空文本内容:cat、sed

cat /dev/null > 11.txt 免交互清空文件内容

sed -i 'd' 11.txt   立即删除文件内容

删除:

“d”  d是操作符,不是选项

cat /dev/null > 11.txt

sed -i ‘d’ 11.txt

指定删除:

删除第三行,打印剩余内容:

sed -n '3d;p' 11.txt

删除2-6行 打印剩余:

sed -n '2,6d;p' 11.txt

删除5-最后一行,打印剩余

sed -n '5,$d;p' 11.txt

除了1-4 行之外全部删除,也就是打印1-4行

sed -n '1,4!d;p' 11.txt

匹配再删除

sed '/o/d' 11.txt

匹配范围删除

sed '/one/,/six/d' 11.txt

删除、过滤出非空行:

sed '/^$/d' 11.txt

过滤非空行

grep -v '^$' 11.txt

.

sed核心功能修改、替换:

操作符:

s:替换字符串

c:整行替换

y:单字符替换,替换前后的字符长度要保持一致,否则报错

替换每行第一个匹配词:

sed -n 's/root/test/p' /etc/passwd

替换每行第二个匹配词:

sed -n 's/root/test/2p' /etc/passwd

全量替换:

sed -n 's/root/test/gp' /etc/passwd

把root开头的前面加上#号

sed -n '/^root/ s/^/#/p' /etc/passwd

对字母字符进行大小写替换:

把大写转换成小写:

\l&:转换小写的特殊符号,使用是需要再前面加\ 转义  \l&:(中间是l不是管道符|)

sed 's/[A-Z]/\l&/g' 22.txt

把小写转换成大写:

\u&:转换大写的特殊符号,使用前面也要加转义符 \

全量替换后面要加g

sed 's/[a-z]/\u&/g' 22.txt

整行替换:

c整行替换,先匹配再替换

sed '/one/c 22' 11.txt

计算题:整行替换

单字符替换:y

要求:被替换和替换字符 要一一对应

sed命令:新增

a:在匹配行的下一行添加内容

i:在匹配行的上一行添加内容

r:可以从其他文件读取内容,然后在匹配行的行后添加

$a:可以直接在文本的最后一行添加内容。

$i:可以在最后一行和倒数第二行中间添加内容,不推荐

sed中字符串和字符串的位置交换:

要用到扩展正则和分组的概念

-r 和 () 替换字符串 s

sed直接通过文件内容当中的命令,来修改第二个文件内容:
-f 通过文件改文件(内容)

计算题:

1、过滤版本号:

2、

总结:

sed可以增删改查

sed也可以结合正则表达式

但是sed的最主要作用:改、增

使用sed命令时,注意,大文件一定要分割后再交给sed处理

搭配扩展正则:sed -r ({n} {n,} {n,m} {,m})

使用sed -i 立即生效,要注意,事先做好测试,还要做好备份

awk

awk是文本三剑客之一,也是功能最强大的文本工具。

逐行读取输入的文本内容,默认以空格和tab键作为分隔符,但是多个空格或者tab键的空格会自动压缩成一个。按照指定的模式或者条件执行编辑命令

也是逐行匹配。对符合条件的才会进行格式化输出或者过滤

可以在免交互的情况下实现复杂的文本操作。完成自动化的配置。

格式:awk都还是跟单引号

awk ‘操作符 action(动作)’ file(文件名)

想干啥  怎么干   处理对象

awk ‘BEGIN{x=1};{x++};END{处理动作}’

BEGIN对条件做初始化操作(类似for循环 for((i=1;i<=10;i++)

awk ‘操作符{处理动作}’ 文件名

{}外部表示定义条件,{}内指定操作。

awk常用选项:

awk -F:指定分隔符,如果分隔符是空格、tab键,可以不加

awk -v:变量赋值。awk这个命令不能从外部获取变量值,只能在内部赋值

主要是内置变量

内置变量:

NR:行号

FS:列分隔符,和F作用一致,如果你用FS  格式是 FS=”:”

OFS:输出内容的列分割符

NF:最后一个字段

$n:打印第n行

awk的基本操作:

打印:

awk '{print}' /etc/passwd 打印文本内容

内置变量:

NR:需要处理行的行号

打印行号:

$0打印所有

.

awk如何进行运算:

awk 'BEGIN{print 计算式}'

awk按行取列:

awk -F ":" '{print $2,$NF}' /etc/passwd

$NF 最后一列

awk不能取连续列,若想取2-5列:

awk -F: ‘{print $2,$3,$4,$5} 11.txt

awk的精确筛选:(这里的n是字段,也就是分割出来的列)

$n(><==):进行数值对比

$n~”字符串”:代表这个字段包含某个字符串

$n!~”字符串”:代表这个字段不包含某个字符串

$n==”字符串”:代表这个字段要和字符串相同,一个字不差

$n!=”字符串”:取反,不为某某个字段

$NF:代表最后一个字段

示例:

  1. /etc/passwd

要求输出最后一个字段中包含bash所在行的第一个字段和最后一个字段

awk -F: '$NF~"bash"{print $1,$NF}' /etc/passwd

2、/etc/passwd

只有第一列是root的行,才打印他的第六列

awk -F: '$1=="root"{print $6}' /etc/passwd

3、/etc/passwd

输出最后一个字段,不包含bash,然后打印第一列和第六列

awk -F: '$NF!~"bash"{print $1,$6}' /etc/passwd

4、/etc/passwd

指定第六个字段为/home/test 而且最后一个字段为/bin/bash,满足条件的输出第一列和最后一列

 awk -F: '($6=="/home/test")&&($NF=="/bin/bash"){print $1,$NF}' /etc/passwd

5、/etc/passwd

打印出第三列数字大于500的,然后输出全部内容

awk -F: '$3>500 {print}' /etc/passwd

条件判断打印:

if语句:

if $3>500 打印所有

awk的三元表达式:

继承了Java,格式和java也一样

awk ’{条件表达式1 ? A表达式或者值:B表达式或者值}’ 文件名

awk -F: '{max=($3>=$4)?$3:$4;{print max $0}}' /etc/passwd

?   if

:  else

if [$3>=$4]

then

echo $3

else

echo $4

fi

文本内容匹配过滤打印:

cat /etc/passwd

过滤出所有包含home的

1 www.123.com

2 mail.456.com

3 ftp.789.com

4 inux.000.com

5 blog.111.com

过滤主机名

getline函数:getline和管道符积极重定向符号在一块的时候

重定向: <  >  把其中一个文件的内容传给另外一个

|:输出指定内容,先到定义的变量,getline调用变量当中的内容,打印指定结果

getline函数运行之后会改变awk的内置变量,读取的行数也就发生变化

getline在前,就是先第一行跳过,再打印

getline在后,就是先打印第一行,跳过第二行

若打印

ls | awk '{getline ky32;print $0,ky32;}'

awk -v 给变量赋值

shell往内部脚本传参:

改变分隔符:

内置变量:

NR:行号

FS:列分隔符,和F作用一致,如果你用FS  格式是 FS=”:”

OFS:输出内容的列分割符

NF:最后一个字段

$n:打印第n行

BEGIN模式:

对变量初始化,要用BEGIN模式

awk 'BEGIN{x=1};{x++};END{print x}' 11.txt

awk和数组结合使用:

awk中定义数:要用到初始化

数组的方式去重:

索引下标是唯一的

 awk '{a[$1]++};END{for (i in a) {print i,a[i]}}' 11.txt

初始值:

awk处理行从0开始

a[$1]=0

awk '{a[$1]++};END{for (i in a) {print i,a[i]}}' 11.txt

awk的代码逻辑和shell不是一个逻辑:

他是awk自己的代码逻辑

111

111

222

333

111

222

111

代码有7行,遍历是按行赋值,所以循环7次

awk处理行从0开始,但是0++,之后相当于从1开始,

a的值会赋给i

a=i

a=111

a=222

a=333

i=111

i=222

i=333

for i in

a[111]=0++=1

a[111]=1++=2

a[222]=0++=1

a[333]=0++=1

a[111]=2++=3

a[222]=1++=2

a[111]=3++=4

得出:

111 4
222 2

333 1

总结:

重点知识点:

awk按行取列:

awk -F: '{print $1,$3}' /etc/passwd

awk的运算格式

awk '{BEGIN{print 1+2}}'

awk精确筛选:

awk -v赋值变量:把shell中的变量传给awk,awk自己不能获取shell中的变量

awk -v a=$a

注意:在awk中,打印变量不需要加$

awk按行、行号、行号范围区间打印 <>==

awk文本内容过滤:和sed很像

awk ‘/root/{print}’ 文件名

awk getline方法:了解即可

awk数组遍历排序去重:

练习:

日志分割:

五大负载监控:

内存监控:free -h

cup监控:

练习:

监控内存 内存的使用百分比不能超过90%、

磁盘不能超过80%

进程不能超过75%

写成函数库,以定时任务的方式

每天早上十点整执行一次。

保留小数点两位:

sum=$(awk 'BEGIN{printf "%.2f", 2.333*3.333}')

保留整数:

sum=$(awk 'BEGIN{printf "%.F", 2.333*3.333}')

监控cup 取值

top -b -n 1 | grep "%Cpu(s)" | awk '{print $4}'

统计etc下所有文件的总大小

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值