文本三剑客 grep sed awk

125 阅读5分钟

一. grep 😊

** grep [选项]… 查找条件 目标文件 **

字符意思
-i查找是忽略大小写
-v反向查找,输出与查找条件不相符的行
-o只显示匹配项
-f对比两个文件相同行
-c匹配行数
-n显示匹配行号
-r递归目录,但不处理软链接
-R递归目录,但处理软链接
-F不支持正则表达式
-c统计匹配到的行数

示例题:

image.png

image.png

image.png

  • -A:after, 后#行
  • -B:before, 前#行
  • -C:context, 前后各#行

image.png

例题2:

image.png

image.png

提取网址

image.png

面试题

统计当前主机的连接状态

统计当前连接主机数

image.png

二.awk

1.awk工作原理:

  • 逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。

  • awk倾向于将一行分成多个"字段"然后再进行处理。

  • awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。

  • 使用awk命令的过程中,可以使用逻辑操作符"&&"表示"与"、"|"表示"或"、"!"表示"非",还可以进行简单的数学运算,如+、-、*、/、%、^分别表示加、减、乘、除、取余和乘方。

2.awk基础用法

1.主要的作用:

用来处理文本,将文本按照指定的格式输出。其中包含了变量,循环以及数组

2.格式:

2.1 awk [选项] '匹配规则和处理规则 ' [处理文本路径]

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

注意:

  • 注意一定是单引号:'模式或条件 {操作}'
  • { }外指定条件,{ }内指定操作。
  • 用逗号指定连续的行,用 || 指定不连续的行。&&表示”且“。
  • 内建变量,不能用双引号括起来,不然系统会把它当成字符串。

3.awk常见的内置变量

内置变量含义
$0当前处理的行的整行内容
$n当前处理行的第n个字段(第n列)
NR当前处理的行的行号(序数)
NF当前处理的行的字段个数。$NF代表最后一个字段
FS列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与"-F"作用相同
OFS输出内容的列分隔符
FILENAME被处理的文件名
RS被处理的文件名

4.awk的基础用法

按行输出内容

示例1:$0表示当前行的整行内容

1.输出所有内容的两种方式

awk '{print $0}' yy.txt  //输出所有内容


awk '{print}' yy.txt    //输出所有内容

image.png

2、打印行号和整行内容。

  awk '{print NR,$0}' yy.txt

image.png

使用NR指定行号

NR表示当前处理的行的行号(序数)。

1、打印1到3行。逗号表示连续的行内容。&&表示”且“。

awk 'NR==1,NR==3 {print $0}' yy.txt //打印1到3行  one

awk '(NR>=1)&&(NR<=3) {print}' yy.txt

image.png

2.注意符号"||"(表示“或“)

awk '(NR>=1)||(NR<=3) {print}' yy.txt //打印所有行  one

awk '(NR==1)||(NR==3) {print}' yy.txt   //打印第1行、第3行  one

image.png

3、打印奇数行;打印偶数行。(将行号除以2取余数,余1是奇数行,余0是偶数行)

awk '(NR%2)==1 {print}' yy.txt   //打印奇数行

awk '(NR%2)==0 {print}' yy.txt //打印偶数行



image.png

示例3:$n 表示当前处理行的第n个字段

获取IP地址。

image.png

示例4:通过文本模式(匹配字符串)过滤出行

1、输出包含root的行。

awk '/root/ {print}' pass.txt //使用awk命令

sed -n '/root/p' pass.txt   //使用sed命令

image.png

2、输出以root开头的行;输出以bash结尾的行。

awk '/^root/ {print}' pass.txt //输出以root开头的行

awk '/bash$/ {print}' pass.txt //输出以bash结尾的行。 


sed -n '/^root/p' pass.txt   //输出以root开头的行

sed -n '/bash$/p' pass.txt   //输出以bash结尾的行。

image.png

grep -c 也可以统计匹配行的行数。

image.png

😊

按字段(列)输出内容

指定列分隔符的两种方式:使用-F 或 使用内建变量FS。

示例1:使用 -F 指定分隔符。

image.png

示例3:打印UID大于500的用户、打印UID小于等于500的用户(!取反)

要求打印用户名和UID。

! 表示取反,不大于500,即小于等于500。

 #以冒号作为分隔符,过滤出第3字段大于500的行,之后打印第1字段和第3字段   awk -F: '3>500 {print 1,$3}' /etc/passwd  ​

 #以冒号作为分隔符,过滤出第3字段小于等于500的行,之后打印第1字段和第3字段
awk -F: '!($3>500) {print $1,$3}' /etc/passwd

image.png

示例4:使用if语句

使用if语句时,内部条件要加( ),外面要加{ }。

将{ }整条语句当作一个操作命令,相当于嵌套。

awk -F: '{if($3>500) {print $1,$3}}' /etc/passwd

image.png

$NF、$n~、$n!~、$n==、$n!=

 NF    //代表最后一个字段 ​  表示包含,! 表示不包含,==表示等于,!=表示不等于 ​ NF         //代表最后一个字段  ​  ~ 表示包含,!~ 表示不包含,== 表示等于,!= 表示不等于  ​  n> < ==     //用于对比数值   n "字符串" //代表第n个字段包含某个字符串的作用 n~"字符串"   //代表第n个字段 包含 某个字符串的作用  n!~"字符串"   //代表第n个字段 不包含 某个字符串的作用  n=="字符串" //代表第n个字段为某个字符串的作用 n=="字符串"   //代表第n个字段 为 某个字符串的作用  n!="字符串"   //代表第n个字段 不为 某个字符串的作用

 通过管道处理其他命令的结果

示例1:统计行数

方法一:使用内置变量NR,打印最后一行行号

处理完文本后,打印行号,这个行号就是最后一行的行号,也就是行数。(这种方式只适用于输出所有行的情况,即只能统计全文本有多少行)

echo $PATH |awk 'BEGIN{RS=":"};{print NR,$0}'

echo $PATH |awk 'BEGIN{RS=":"};END{print NR}'

方法二:使用"wc -l" 统计行数

  # awk -F: '/bash$/{print}' pass.txt
  
 # awk -F: '/bash$/{print}' pass.txt |wc -l

 # awk -F: '/bash$/{print |"wc -l"}' pass.txt




grep -c "bash$" pass.txt 统计行数

统计内存使用率

free命令可以查看内存使用情况。

使用率=使用的内存数量/总内存数量。

int表示取整数。

 [root@yu ~]# free               total       used       free     shared buff/cache   available  Mem:         999696      310872      319996        7400      368828      491760  Swap:       2097148           0     2097148

  [root@yu ~]# free | awk '/Mem:/ {print $3/$2}'
  0.311223

 [root@yu ~]# free | awk '/Mem:/ {print $3/$2*100}'
 31.1223
 [root@yu ~]# free | awk '/Mem:/ {print int($3/$2*100)}'
 31
   [root@yu ~]# free | awk '/Mem:/ {print int($3/$2*100)"%"}'
   31%

过滤出CPU的空闲率

top命令可以查看CPU的使用情况。

top -b -n 1 只会输出一次top的结果 不会进行刷新 。

 [root@yu ~]# top -b -n 1
 top - 18:45:59 up  4:46,  3 users,  load average: 0.04, 0.08, 0.06
 Tasks: 149 total,   1 running, 148 sleeping,   0 stopped,   0 zombie

 %Cpu(s):  0.0 us,  6.2 sy,  0.0 ni, 93.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 s  KiB Mem :   999696 total,   317456 free,   311324 used,   370916 buff/cache  KiB Swap:  2097148 total,  2097148 free,        0 used.   491288 avail Mem  [root@yu ~]# top -b -n 1 |awk -F, '/Cpu/{print $4}'  100.0 id

[root@yu ~]# top -b -n 1 |awk -F, '/Cpu/{print $4}' |awk '{print $1}'

 100.0

[root@yu ~]# top -b -n 1 |awk -F, '/Cpu/{print $4}' |awk '{print int($1)}'

 85

[root@yu ~]# top -b -n 1 |awk -F, '/Cpu/{print $4}' |awk '{print int($1)"%"}'

 

案例

通过分析日志 /var/log/secure 查看哪些主机在暴力破解本机服务,如果统计出密码验证失败超过三次(不考虑连续性),就把IP加入到黑名单中 /etc/hosts.deny。86%

 #过滤出包含“Failed password”的行,打印第11个字段,且按照数字排序  [root@yuji ~]# awk '/Failed password/{print 11}' /var/log/secure |sort -n  192.168.72.10  192.168.72.10  192.168.72.10   192.168.72.10   192.168.72.192  192.168.72.192  192.168.72.192  ​  #统计重复行出现的次数   [root@yu ~]# awk '/Failed password/{print 11}' /var/log/secure |sort -n |uniq -c        4 192.168.72.10        3 192.168.72.192  ​

#判断重复的次数如果大于3次,则在IP前加上"sshd:",并将其追加进/etc/hosts.deny文件中

 [root@yu ~]# awk '/Failed password/{print 11}' /var/log/secure |sort -n |uniq -c| awk '1>3 {print "sshd:"$2}' >>/etc/hosts.deny  ​

#查看etc/hosts.deny文件

 [root@yu ~]# cat /etc/hosts.deny

sshd:192.168.72.10

三.sed

简介:

sed 即 Stream EDitor,和 vi 不同,sed是行编辑器

Sed是从文件或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行,直到最后一行。每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间(PatternSpace),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。一次处理一行的设计模式使得sed性能很高,sed在读取大文件时不会出现卡顿的现象。如果使用vi命令打开几十M上百M的文件,明显会出现有卡顿的现象,这是因为vi命令打开文件是一次性将文件加载到内存,然后再打开。Sed就避免了这种情况,一行一行的处理,打开速度非常快,执行速度也很快。

image.png

1.基本用法

格式:  sed [ 选项 ].... 'script;script;....'(自身脚本语法) [input file...]

常用选项:

  • -n 不输出模式空间内容到屏幕,即不自动打印
  • -e 多点编辑[root@www data]#sed -n -e '/^r/p' -e'/^b/p' /etc/passwd
  • -f FILE 从指定文件中读取编辑脚本
  • -r, -E 使用扩展正则表达式
  • -i.bak 备份文件并原处编辑
  • -s  将多个文件视为独立文件,而不是单个连续的长文件流
sed ' ' /etc/fstab
##查看文件内容,sed自带打印功能

sed ''</etc/fstab
##支持重定向

cat /etc/issue |sed ''
也支持管道符

image.png

2.sed脚本格式

单引号中间需要写脚本,脚本格式如下

脚本内容由'地址+命令'组成

地址表示:
1. 不给地址:对全文进行处理(比如行号)
2. 单地址:
  #:指定的行,$:最后一行
  /pattern/:被此处模式所能够匹配到的每一行,正则表达式
       3. 地址范围:
   #,#     #从#行到第#行,3,6 从第3行到第6行
   #,+#   #从#行到+#行,3,+4 表示从3行到第7行
  /pat1/,/pat2/    第一个正则表达式和第二个正则表达式之间的行
   #,/pat/  从#号行为开始找到 pat为止 
  /pat/,#  找到#号个pat为止
4. 步进:~
  1~2 奇数行
   2~2 偶数行 
  
  
  

   

 

 

image.png

image.png

命令

 p 打印当前模式空间内容,追加到默认输出之后
 Ip 忽略大小写输出
d 删除模式空间匹配的行,并立即启用下一轮循环
a [\]text 在指定行后面追加文本,支持使用\n实现多行追加
i [\]text 在行前面插入文本
c [\]text 替换行为单行或多行文本
w file 保存模式匹配的行至指定文件
r file 读取指定文件的文本至模式空间中匹配到的行后
= 为模式空间中的行打印行号
! 模式空间中匹配行取反处理
 q           结束或退出sed

示例1:打印网卡ip

ifconfig ens33|sed -n '2p'

image.png

示例2:支持正则表达式

image.png

也可以匹配正则表达式之间的行/ /,/ /

举例显示/etc/passwd 中b开头和f开头中间的行

先开始找b开头一直找到f开头
  然后再重新找b开头,一找到f开头,没有f开头就全显示
 重复循环

image.png

示例3:在指定行前后添加i 、a

image.png

示例4:\ 空格 \n 表示换行

image.png

示例5:取反

image.png

3.搜索替代

格式:sed -i 's///' 文件名

替换修饰符:

  • g 行内全局替换
  • p 显示替换成功的行
  • w   /PATH/FILE 将替换成功的行保存至文件中
  • I,i   忽略大小写

s/pattern/string/修饰符 查找替换,支持使用其它分隔符,可以是其它形式:s@@@,s###

4.变量

 name=root
 sed -nr '/'$name'/p' /etc/passwd
 rootec:x:0:0:root:/root:/bin/bash
 operator:x:11:0:operator:/rootec:/sbin/nologin

image.png