Linux之awk:按照字符或列进行筛选与计算列值 条件动作
Linux三剑客之awk命令
文章共1,472字 · 阅读需要大约5分钟
一键AI生成摘要,助你高效阅读
问答
·
1 语法
awk '条件1{动作1} 条件2{动作2}...'文件名
条件(Pattern):一般使用关系表达式作为条件--x > 10判断变量x是否大于10
动作(Action):格式化输出流程 --控制语句
1.1条件
1.1.1BEGIN与AFTER
[root@localhost ~]# awk 'BEGIN{printf "This is a transcript \n" } {printf $2 "\t" $6 "\n"}' student.txt
#awk命令只要检测不到完整的单引号不会执行,所以这个命令的换行不用加入“\”,就是一行命令
#这里定义了两个动作
#第一个动作使用BEGIN条件,所以会在读入文件数据前打印“这是一张成绩单”(只会执行一次)第二个
动作会打印文件的第二字段和第六字段
[root@localhost ~]# awk 'END{printf "The End \n" } {printf $2 "\t" $6 "\n"}' student.txt
#在输出结尾输入“The End”,这并不是文档本身的内容,而且只会执行一次
1.1.2关系运算符
假设我想看看平均成绩大于等于87分的学员是谁,就可以这样输入命令:例子1:
[root@localhost string]# cat student.txt
id name esex makr
1 qq aa 34
2 xx cc 45
3 tt vv 55
[root@localhost string]# cat student.txt | grep -v name | awk '$4 >= 40 {printf $2 "\n" }'
xx
tt
[root@localhost ~]# awk '$2 ~ /Sc/ {printf $6 "\n"}' student.txt
#如果第二字段中输入包含有“Sc”字符,则打印第六字段数据85.66这里要注意在awk中,使用“//”包含的字符
串,awk命令才会查找。也就是说字符串必须用“//”包含,awk命令才能正确识别。
~ 和 !~ 匹配正则表达式和不匹配正则表达式
有$的话 必须使用~ 进行正则匹配
1.1.3正则表达式
如果要想让awk识别字符串,必须使用“//”包含,例如:例子1:
[root@localhost ~]# awk '/Liming/ {print}' student.txt
#打印Liming的成绩
当使用df命令查看分区使用情况是,如果我只想查看真正的系统分区的使用状况,而不想查看光盘和临时分区
的使用状况,则可以:例子2:
[root@localhost ~]# df -h | awk '/sda[0-9]/ {printf $1 "\t" $5 "\n"} '
#查询包含有sda数字的行,并打印第一字段和第五字段
1.2awk内置变量
[root@localhost ~]# cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'
[root@localhost ~]# cat /etc/passwd | grep "/bin/bash" | \awk 'BEGIN {FS=":"} {printf $1
"\t" $3 "\t 行号:" NR "\t 字段数:" NF "\n"}'
#解释下awk命令
#开始执行{分隔符是“:”} {输出第一字段和第三字段输出行号(NR值)字段数(NF值)}
root 0 行号:1 字段数:7
user1 501 行号:2 字段数:7
如果我只想看看sshd这个伪用户的相关信息,则可以这样使用:
[root@localhost ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $1=="sshd" {printf $1 "\t" $3 "\t 行号:"NR "\t 字段数:"F " \n"}'
#可以看到sshd伪用户的UID是74,是/etc/passwd文件的第28行,此行有7个字段
1.3awk流程控制
加和
[root@localhost ~]# awk 'NR==2{php1=$3} NR==3{php2=$3} NR==4{php3=$3;totle=php1+php2+php3;print "totle php is " totle}' student.txt
#统计PHP成绩的总分
我们解释下这个命令。“NR==2{php1=$3}”(条件是NR==2,动作是php1=$3)这句话是指如果输入数据是第二行
(第一行是标题行),就把第二行的第三字段的值赋予变量“php1”。“NR==3{php2=$3}”这句话是指如果输入数
据是第三行,就把第三行的第三字段的值赋予变量“php2”。“NR==4{php3=$3;totle=php1+php2+php3;print
"totle php is " totle}”(“NR==4”是条件,后面{}中的都是动作)这句话是指如果输入数据是第四行,就把
第四行的第三字段的值赋予变量“php3”;然后定义变量totle的值是“php1+php2+php3”;然后输出“totle php
is”关键字,后面加变量totle的值。
if与赋值
假设如果Linux成绩大于90,就是一个好男人
[root@localhost ~]# awk '{if (NR>=2) {if ($4>90) printf $2 " is a good man!\n"}}'
student.txt #程序中有两个if判断,第一个判断行号大于2,第二个判断Linux成绩大于90分Liming is a
good man!Sc is a good man!
[root@localhost ~]# awk ' NR>=2 {test=$4} test>90 {printf $2 " is a good man!\n"}'
student.txt
#先判断行号如果大于2,就把第四字段赋予变量test
#在判断如果test的值大于90分,就打印好男人Liming is a good man!Sc is a good man!
自定义函数
[root@localhost string]# awk 'function test(a,b) { printf a "\t" b "\n" } { test($2,$3) }' student.txt
name esex
qq aa
xx cc
tt vv
调用脚本-f
[root@localhost ~]# vi pass.awkBEGIN {FS=":"}{ print $1 "\t" $3}
[root@localhost ~]# awk -f pass.awk /etc/passwd
root 0
bin 1
daemon 2
例子
统计日志中INFO,ERROR出现的总数,以及总记录数
awk '
BEGIN {
FS="@"
}
{
if ($3 == "INFO") {info_count++}
if ($3 == "ERROR") {error_count++}
}
END {
print "order total count:"NR
printf("INFO count:%d ERROR count:%d\n",info_count,error_count)
} ' demo.log_after_sort
order total count:22
INFO count:5 ERROR count:17
更多推荐
已为社区贡献4条内容
所有评论(0)