linux三剑客
1、三剑客应用场景
特点 | 命令 | 场景 |
---|---|---|
grep | 过滤 | grep命令过滤最快 |
sed | 替换,修改文件内容,取行 | 如果要进行替换/修改内容; 取出某个范围内的内容(从11:00到12:00) |
awk | 取列,统计计算 | 取列 对比,比较 >= <= !- > < 统计,计算(awk数组) |
2三剑客-grep
选项 | 含义 |
---|---|
-E | ==egrep 支持扩展正则 |
-A | 了解,after,-A5匹配你要的内容并显示接下来的5行 |
-B | 了解,before,-A5匹配你要的内容并显示接上面的5行 |
-C | context,上下文-C5匹配你要的内容并显示上下5行 |
-c | 统计出现的次数,相当于wc -l |
-v | 取反,排除 |
-w | 精确匹配,左边没东西,右边也没东西 |
[root@nn-01 ~]# seq 10 |grep 3 -A5
3
4
5
6
7
8
3三剑客-sed
3.1 特点及格式
-
sed stream editor 流编辑器,sed把处理的内容(文件),当作水流,源源不断的进行处理,知道文件末尾
-
sed格式
命令 选项 (s)sed命令功能(g)修饰符 参数(文件) sed -r ‘s#oldboy#oldgirl#g’ oldboy.txt -
sed功能的核心功能:增删改查
功能 s 替换substitute p 显示print d 删除delete cai 增加c/a/i
3.2 sed命令的执行过程
把文件中一行一行读取到内存中,好比做水流,判断执行相应的操作。
3.3 sed命令的核心应用
1)sed-查找p
查找格式 | 解释 |
---|---|
‘2p’ | 指定行进行查找 |
‘1,5p’ | 指定行号范围进行查找 |
‘/lidao/p’ | 类似于grep,过滤,//里面可以写正则 |
‘/10:00/,/11:00/p’ | 表示范围的过滤 |
2)sed-删除d
删除格式 | 解释 |
---|---|
‘2d’ | 删除指定行 |
’1,5d‘ | 删除指定行号范围的行 |
’/lidao/d‘ | 删除包含lidao的行,//里面可以写正则 |
‘/10:00/,/11:00/d’ | 删除指定范围的行,如果指定的结尾匹配不到,就一直匹配到最后一行,和’’/10:00/,$d’同意。 |
3)sed-增加cai
命令 | 解释 |
---|---|
c | replace 替代这行内容 |
a | append 在指定内容后追加 |
i | insert 在指定行之前插入 |
4)sed-替换s
- s substitute 替换
- g gloabal 全局的,sed命令,默认只替换每行第一个匹配到的内容。
- 如果要替换的内容为空,相当于删除的作用
- 反向引用,‘s#()#\1#g’,用括号括起来想要引用的内容,用\1、\2引用
格式 |
---|
’s###g‘ |
4三剑客-awk
4.1awk的执行过程
awk -F, 'BEGIN{print"begin of file"}{print $2}END{print "end of file"}'
过程 | 执行 | 举例 |
---|---|---|
读取文件之前 | 命令赋值或者命令行参数 | -F, |
BEGIN | BEGIN{print"begin of file"} | |
读取文件中 | 执行过程类似sed命令,一行一行读取执行 | {print $2} |
读取文件后 | END | END{print “end of file”} |
4.2行与列
名词 | awk中的叫法 | 一些说明 |
---|---|---|
行 | 记录 record | 每一行默认是通过回车分割的 |
列 | 字段,域field | 每一列默认是通过空格分割的 |
awk中的行和列的分割符都是可以修改的 |
1)取行
awk | a |
---|---|
NR==1 | 取出第一行 |
NR>=1 && NR<=5 | 取出第1行到第5行 范围 |
/oldboy/ | |
/101/,/105/ | |
符号 | > < >= <= == != |
2)取列
-
-F 指定分隔符 指定每一列结束标记(默认是空格,连续空格,tab键)
-
数 字 取 出 某 一 列 , 注 意 : 在 a w k 中 数字 取出某一列,注意:在awk中 数字取出某一列,注意:在awk中内容一个意思,表示取出某一列
-
0 表 示 整 行 的 内 容 , 0表示整行的内容, 0表示整行的内容,NF表示最后一列
[hadoop@db48 ~]$ #取出第一块网卡中的ip地址,取出指定行指定列的内容。 [hadoop@db48 ~]$ ip a s eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1454 qdisc pfifo_fast state UP qlen 1000 link/ether 52:54:00:5b:87:da brd ff:ff:ff:ff:ff:ff inet 10.10.110.33/16 brd 10.10.255.255 scope global eth0 valid_lft forever preferred_lft forever [hadoop@db48 ~]$ ip a s eth0 |awk 'NR==3'|awk -F"[ /]+" '{print $3}' 10.10.110.33 [hadoop@db48 ~]$ ip a s eth0 |awk -F"[ /]+" 'NR==3{print $3}' 10.10.110.33
4.3匹配模式
- 谁可以作为awk的条件
- 比较符号:> < >= <= == !=
- 正则
- 范围表达式
- 特殊条件 BEGIN和END
awk | -F"[ /]+" | ‘NR==3{print $3}’ |
---|---|---|
命令 | 选项 | ’条件{动作}‘ |
’模式{动作}‘ | ||
’partten{action}‘ |
1)比较表达式-参考上面取行部分
2)正则
- //支持扩展正则
- awk可以精确到某一列,某一行中包含/不包含…内容
- ~包含
- !~不包含
正则 | awk正则 |
---|---|
^表示以……开头 | 某一列的开头 $3~/^oldboy/ |
$表示以……结尾 | 某一列的结尾 4 / l i d a o 4~/lidao 4 /lidao/ |
#找出/etc/password中第三列以2开头的行,显示第一列,第三列和最后一列
[hadoop@db48 ~]$ tail -10 /etc/passwd
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
zsw:x:1000:1000::/home/zsw:/bin/bash
lxq:x:1001:1001::/home/lxq:/bin/bash
hadoop:x:1002:1002::/home/hadoop:/bin/bash
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false
gj:x:1003:1003::/home/gj:/bin/bash
tmh:x:1004:1004::/home/tmh:/bin/bash
zzl:x:1005:1005::/home/zzl:/bin/bash
phy:x:1006:1006::/home/phy:/bin/bash
wbq:x:1007:1007::/home/wbq:/bin/bash
[hadoop@db48 ~]$ awk -F':' '$3~/^2/{print $1,$3,$NF}' /etc/passwd
daemon 2 /sbin/nologin
nscd 28 /sbin/nologin
mysql 27 /bin/false
3)表示范围
- /哪里开始/,/哪里结束/常用
- NR1,NR5从第一行开始,到第五行结束。类似于 sed -n ‘1,5p’
#显示指定时间范围(11:02:00到11:02:30)范围内的ip地址
awk '/11:02:00/,/11:02:30/{print $1}' access.log
4)特殊模式BEGIN{}和END{}
模式 | 含义 | 应用场景 |
---|---|---|
BEGING{} | 里面的内容会在awk***读取文件之前执行*** | 1)进行简单的统计,计算,不涉及读取文件(常用) 2)用来处理文件之前,添加个表头(了解) 3)用来定义awk变量(很少用,因为可以用-v) |
END{} | 里面的内容会在awk读取文件之后执行 | 1)awk进行统计,一般过程:先进行计算,最后END里面输出结果(常见) 2)awk使用数组,用来输出数组结果(常见) |
- END统计计算
- 统计方法:
统计方法 | 简写形式 | 应用场景 |
---|---|---|
i=i+1 | i++ | 计数,统计次数 |
sum=sum+??? | sum+=??? | 求和,累加 |
array[]=array[]++ | array[]++ | 数组分类统计,计数 |
注意:i,sum都是变量 |
#统计/etc/services里面多少个空行
[hadoop@db48 ~]$ awk '/^$/' /etc/services |wc -l
17
[hadoop@db48 ~]$ awk '/^$/{i++}END{print i}' /etc/services
17
#seq 100 求和1+2+3+……+100 awk实现
[hadoop@db48 ~]$ seq 100 |awk '{sum=sum+$1}END{print sum}'
5050
#如果查看过程
[hadoop@db48 ~]$ seq 100 |awk '{sum=sum+$1;print sum}END{print sum}'
4.4awk数组
- 统计日志:
- 统计次数:统计每个ip出现的次数,统计每种状态码出现的次数,统计系统中每个用户被攻击的次数,统计攻击者ip出现的次数
- 累加求和:统计每个ip消耗的流量
shell数组 | awk数组 | ||
---|---|---|---|
形式 | array[0]=oldboy array[1]=lidao | array[0]=oldboy array[1]=lidao | |
使用 | echo ${array[0]} | print array[0] | |
批量输出数组内容 | for i in ${array[*]} do echo $i done | for(i in array) print array[i] | awk数组专用循环,变量获取到的是数组的下标,你想要数组的内容array[i] |
[hadoop@db48 ~]$ awk 'BEGIN{a[0]=oldboy;a[1]=lidao;print a[0],a[1]}'
#awk中的字母,会被识别成变量,如果只是想使用字符串需要加上双引号""
[hadoop@db48 ~]$ awk 'BEGIN{a[0]="oldboy";a[1]="lidao";print a[0],a[1]}'
oldboy lidao
[hadoop@db48 ~]$ awk 'BEGIN{a[0]="oldboy";a[1]="lidao";for(i in a) print i,a[i]}'
0 oldboy
1 lidao
#统计域名出现的次数并倒序排列
[hadoop@db48 tmp]$ cat url.txt
://jingyan.baidu.com/article/6079ad0e7744e869fe86db18.html
https://www.baidu.com/s?ie=UTF-8&wd=typoro%E8%B7%B3%E5%87%BA%E5%88%97%E8%A1%A8
https://www.baidu.com/s?ie=UTF-8&wd=ll%20%E6%96%87%E4%BB%B6%E9%A2%9C%E8%89%B2
https://blog.csdn.net/qq_29242127/article/details/77141485
https://blog.csdn.net/qq_29242127/article/details/77141485
https://blog.csdn.net/qq_29242127/article/details/77141485
#sort -r(倒序) -n(数字) -k2(第二列)
[hadoop@db48 tmp]$ awk -F"[/]+" '{array[$2]++}END{for(i in array) print i,array[i]}' url.txt |sort -rnk2
blog.csdn.net 3
www.baidu.com 2
jingyan.baidu.com 1
4.5awk循环,判断
shell编程c语言for循环 | awk for循环 | |
---|---|---|
for((i=1;i<=10;i++)) do echo $i done | for(i=1;i<=10;i++) print i | awk for循环用来循环每个字段 |
#1+100
[hadoop@db48 tmp]$ awk "BEGIN{for(i=1;i<=100;i++)sum+=i;print sum}"
5050
[hadoop@db48 tmp]$ awk "BEGIN{
for(i=1;i<=100;i++)
sum+=i;
print sum
}"
5050
[hadoop@db48 tmp]$ awk "BEGIN{
for(i=1;i<=100;i++)
{sum+=i;
print sum}
}"
5050
shell编程if条件句 | awk if条件判断 | |
---|---|---|
if[“oldhuang” -eq 18];then echo take to dbj fi | if(条件) print “dbj” | |
if[“oldhuang” -eq 18];then echo take to dbj else echo "rest" fi | if() print "dbj" else print “rest” |
#找出磁盘利用率大于70%的磁盘,并打印Filesystem,Size,Used
[hadoop@db48 ~]$ df -h|awk -F"[ %]+" 'NR>1{if($5>70) print "Disk is not enough\t" $1,$2,$5}'
Disk is not enough /dev/vda1 20G 77
#注意:awk如果有多个判断条件,第一个条件可以放在'条件{动作}’,第二个条件一般使用if
#面试题, 统计下面语句中,单词数小于6的单词并显示出来
#I am oldboy teacher welcom to oldboy teacher class
[hadoop@db48 ~]$ echo I am oldboy teacher welcom to oldboy teacher class|awk '{
for(i=1;i<=NF;i++)
if(length($i)<6)
print $i
}'
I
am
to
class
4.6awk内置变量
内置变量 | 含义 |
---|---|
NR | Number of Record 记录号,行号 |
NF | Number or Field 每行有多个字段(列) $NF表示最后一列 |
FS | -F: == -v FS=: Field Separator 字段分隔符,每个字段结束标记 |
OFS | Output Filed Separator 输出字段分隔符(awk显示每一列的时候,每一列之间通过什么分割,默认是空格) |
4.7总结
-
gawk gnu awk
-
awk选项 -F -v
-
awk执行流程
-
awk取行与取列
-
awk模式:比较,正则,范围,特殊模式
-
awk数组:统计分析日志
-
awk for循环,if条件判断
-
目标:
- access.log统计每个ip出现的次数,统计每种状态码出现的次数
- secure统计系统同种每个用户被攻击的次数,统计攻击者ip出现的次数
-
累加求和:统计每个ip消耗的流量