linux action 命令,Linux文本处理三剑客——awk命令使用教程

一、awk的作用于命令格式

awk相对于grep进行文本内容查找、sed文本内容编辑,它更擅长对文本进行过滤并处理。awk和sed一样会把需要处理的文本按行读取到内存中,根据用户需要去灵活的处理文本并打印出来。awk命令格式如下:

awk option 'BEGIN{}/pattern/{action}END{}' filename

#单引号内的是awk程序

#因为awk经常会用到$符号,为了防止$被当成变量被解析,尽量使用单引号

#每个{}内的代码都是单独的代码块,可以存在多个{}

option部分用来指定命令选项,常用选项介绍:

1、-F:在awk中默认的分隔符是空白符(包含空格和制表符),使用-F选项可以自定义分隔符,支持指定多个分隔符

awk -F':' '{print $1}' /etc/passwd #指定分隔符为冒号

netstat -n | grep EST | awk -F '[ :]+' '{print $4}' #空格或冒号为分隔符,并且利用正则将相连的多个符号当做一个分隔符处理

3de076c944b94312715ea7f962782782.png

2、-f:从指定的配置文件中读取awk命令,较少使用

awk -f awk.conf test.txt

3、-v:使用该选项可以定义变量,每一个“-v”定义一个变量

awk -v age=10 '{print age}'

action部分用来指定需要做的具体操作

{action}也叫做main代码块,用来指明awk读取每行文件时需要做的操作。默认操作为{print $0},也就是输出当前行。print和printf是最常用的awk操作(printf可以做格式化,比如左右对齐等),也可以增加自己需要打印出来的东西,这部分内容需要用引号,否则会被当做变量

print格式化输出:

e70fd803df8751307c05e26fd385e61e.png

printf格式化输出,实现了对齐:

f91861f1bffcd8e24870bc67b778d304.png

printf格式化说明:

%s 字符类型

%d 数值类型

%f 浮点类型

-表示左对齐,默认是右对齐

printf不会自动换行,需要加\n

pattern部分,用来做内容匹配,支持正则表达式

~与!~:代表对后面的内容做匹配或取反

awk -F: '$5~/root/{print $1} /etc/passwd' #第5个字段匹配root

awk '$0~/qq.com/{print $0}' a.txt #找出包含qq.com的行

2c1fa584f63ab6b46f983092772d18d4.png

//,//:范围匹配

awk '/12:48:01/,/13:30:00/{print $0}' /var/log/message #过滤出指定时间范围的日志

&&或者||:逻辑与或者逻辑或

cat /var/log/message | awk '$3=="linuxe" || $3 == "tanglu"'

==:完全精准匹配,非模糊匹配,看下面示例:用操作符做完全匹配,可以看到nologins虽然包含了nologin,但是最终结果并没有将其匹配出来

ed930c52e591dbf315c7724c957933f6.png

!=:将过滤结果进行反选后进行匹配

awk '$3!="linuxe"' /etc/passwd

>=:大于等于,当然也有<=、>、

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

二、awk的内置变量

$0:当前行

$n:位置变量,如print $1就是显示第一列的内容,也可以同时显示多列

4f0864ea5dc7b069b06536f0585bff5c.png

FS:输入字段分隔符,默认为空白字符,作用和-F选项类似

awk -v FS=':' '{print $1}' /etc/passwd

OFS:输出字段分隔符,默认为空白字符

awk -v OFS=':' '{print $2,$3}'/etc/passwd

FIELDWIDTHS:以宽度作为分隔符,适合处理一些有字段缺失内容的文本

echo "AABBBCCCCDDDDD" | awk 'BEGIN{FIELDWIDTHS="2 3 4 5"}{print $1;print $2;print $3;print $4}' #第一个字段2个字符‘第二个字段3个字符...

awk 'BEGIN{FIELDWIDTHS="2 2:6 2:6 2:13"} test.txt #第一个字段2个字符,第二个字段跳过2个字符然后取6个字符...

FPAT:使用正则匹配字符作为字段,适合于字段中包含了分隔符的场景,比如用逗号分隔,但是有一个字段中的文本又包含了逗号

RS、ORS:输入换行符与输出换行符,通常要写在BEGIN代码块中,否则第一行文本不会受到影响

awk 'BEGIN{ORS=","}{print $0}' /tmp/ip.txt #将默认的回车换行替换为逗号,实现将多行内容整合到一行,并用逗号分割

BEGIN{ }与END{}:分别是在开始处理文本之前和处理完文本以后,执行一次且只执行一次的命令

awk -F: 'BEGIN{print "username uid\n-----------------"}{print $1,$3}' /etc/passwd

awk 'BEGIN{print "我在开始"}{print $0}' a.txt

awk 'END{print "我在结尾"}{print $0}' a.txt

awk 'BEGIN{print "我在开始"} {print $0} END{print "我在结尾"} a.txt

NF:会记录awk命令所处理的每一行数据有几列字段。比如一行文字被分隔符为7列,那么{print NF}出的结果会显示成7。在awk中引用变量无需加$符号,如果是{print $NF},那么显示的结果就是具体第7列的值了,这个常用于直接显示每一行最后一个字段的值。还可以进行一些数学运算,{print $(NF-1)},结果就是倒数第二行

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

NR和FNR:打印出每一行的行号,不过在处理多个文件时有一点点区别,NR会直接把多个文件的行数依次显示出来,而FNR则对单个文件做行数的显示。看看示例:

fb895511498506bfa5a69f1d757b6627.png

NR通常用于取指定行内容:

cat /etc/passwd | awk 'NR>1 && NF<5{print $0}'

cat /etc/passwd | awk 'NR==3{print $0}' #取出第三行内容

三、awk常用函数

# lentsh(str) 计算括号内字符串长度

# tolower(str) 将括号内字符串转换为小写

# toupper(str) 将括号内字符串转换为大写

# match(str,RE) 返回正则表达式匹配到的字符串的位置

# sub(RE,Repstr,str) 替换查找到的第一个字符串

# gsub(RE,Repstr,str) 替换查找到的所有字符串

四、awk数据筛选示例

1、根据行号筛选

awk 'NR==2' a.txt #筛选出第二行

awk 'NR>2' a.txt #筛选出第二行和之后的行

2、根据正则筛选

awk '/qq.com/' a.txt #筛选带有qq.com的行

awk '$0~/qq.com/{print $0}' a.txt #等价上面的命令

awk '$0~!/qq.com/{print $0}' a.txt #筛选不包含qq.com的行

3、根据字段进行筛选

awk '$5~/qq.com/{print $0}' a.txt #筛选第五个字段中包含qq.com的行

4、多个条件组合进行筛选

awk '$3=="male" && $6~/^170/{print $0}' a.txt #输出第三个字段为male且第6个字段以170开头的行

5、按照范围进行筛选

awk 'NR==2,NR==7' a.txt #输出第2到7行内容

awk 'NR==2,$6~/^170/' a.txt

6、从ifconfig命令中筛选出除了lo网卡外的所有IPv4地址

ifconfig | awk '/inet / && !($2 ~ /^127/){print $2}'

7、使用awk if实现判断

#可以遵循写法:{ if(){} else if(){} else if(){} else{} }

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

awk -F: '{if ($3~/^linuxe){print $0}}' /tmp/1.txt

awk -F: '{if($3==0){print $1,"the user is root"} else if($3>=500){print $1,"is common user"}}' /etc/passwd

8、awk数组。AWK默认支持关联数组(即索引下标可以是单词而不局限于数字),数组的语法格式

array_name[index]=value

#array_name:数组名称

#index:索引元素

#value:元素索引对应的值

awk数组功能常用于对某个字段出现的次数进行统计,比如日志文件中某IP访问了多少次等。要实现这种功能的话只需要定义一个数组,然后把需要统计的字段作为数组的索引即可。

#计算当前系统中普通用户和管理员的个数并显示出来,这里count和i都是定义的变量

awk -F: '{if($3==0){count++} else{i++}} END {print “管理员个数:”count ; print “普通用户数:”i}' /etc/passwd

#使用awk进行计算,可用于统计某进程消耗资源。比如服务器Nginx启动了8个进程,那么该命令会将第一个进程消耗的CPU资源与后面依次相加,最后输出结果,当变量遇到与数值相加时默认是0,所以最后输出的结果就是1+2+3+4...=的结果了

ps aux |grep nginx |awk '{a=a+$3}END{print a}'

#统计访问日志中各个状态码的百分比

cat access.log | awk '{count[$9]++} END {for (status in count ){print status,count[status]/NR*100"%"}}'

#统计Nginx日志中每个IP访问量

awk '{ipcount[$1]++} END{for(i in ipcount){print i,ipcount[i]}}' access.log

#将日志中$1字段作为索引元素赋值给数组ipcount,所以该数组内容是ipcount[192.168.100.1]、ipcount[192.168.100.2]这样的每个IP;

#由于每个索引元素的值默认是1,然后每个索引元素的值会根据awk处理的次数进行递增

#for循环遍历ipcount数组的索引并赋值给变量i,此时变量i就是每个ip

#ipcount[i]就是取数组每个索引的值,i已经定义为ip,所以最后得到的就是自增结束后的总值,实现了统计

#统计日志中访问量最高的页面

awk '/05\/Sep\/2018/{url[$7]++} END{for(i in url){print i,url[i]} }' access.log |sort -k2 -rn

#统计TCP连接数。这里的$6是连接状态,比如LISTEN、ESTABLISHED等,把这个作为status变量的索引进行统计,然后最终输出

netstat -na | grep 80 | awk '{status[$6]++} END {for (i in status){print i,status[i]} }'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值