awk用法详解

本文详细解析了Awk命令的基本语法、内置变量及各种应用场景,包括数据处理、文本分析和统计计算,是学习Awk的强大指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载地址:https://www.cnblogs.com/ginsonwang/p/5102668.html

零、awk的基本知识

 

1、awk命令形式:

awk [-F|-f|-v] ‘BEGIN{} // {command1; command2} END{}’ file

 

2、awk语法解释:

[-F|-f|-v]

大参数。-F指定分隔符,-f调用脚本,-v定义变量 var=value

'  '

引用代码块。

BEGIN

初始化代码块。在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符

//

匹配代码块。可以是字符串或正则表达式

{}

命令代码块。包含一条或多条命令,多条命令使用分号分隔

END

结尾代码块。在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

 

3、awk内置变量:

FILENAME  

awk浏览的文件名  

 

FNR  

与NR类似,不过多文件记录不递增,每个文件都从1开始  

 

FS  

设置输入字段分隔符,同- F选项

 

NF

浏览记录的字段个数

awk '{print NF}' file    //显示每行有多少字段

$NF

最后一个字段的值

awk '{print $NF}' file    //将每行第NF个字段的值打印出来

NR

已读的记录数,理解为行号,多文件行号递增

awk 'NR==5{print}'  file    //显示第5行

OFS

输出数据时,每个字段间以OFS制定的字符作为分隔符

awk '{print $3,$5,$4}' OFS="\n" file

ORS

输出数据时,每行记录间以OFS制定的字符作为分隔符

awk '{print $3,$5,$4}' ORS="\n" file

 

 

一、awk的大参数

awk [-F|-f|-v] 'BEGIN{} // {command1; command2} END{}' file

 

1、-F 指定分隔符

可不写,不写时默认空格为分隔符

一个或多个连续的空格看做一个分隔符,即多个空格看做一个空格

可以定义多个分隔符,如 -F[./] 是指,同时以“.”和“/”作为分隔符

 

2、-f 与 -v

(暂时不必接触这部分内容)

 

二、awk的引用代码块

awk [-F|-f|-v] ‘BEGIN{} // {command1; command2} END{}’ file

 

1、操作符

综合看引用代码部分实际上相当于一个编程环境,支持很多操作符。如条件运算操作符、逻辑运算操作符等。

 

==

等于,精确比较

awk '$3=="48" {print $0}' file    只打印第3个字段等于"48"的记录

!=

不等于,精确比较

awk '$1 != "abc"' file    //提取第一个字段不是abc的行

~

匹配,与==相比不是精确比较

awk '{if ($4~/abc/) print $0}' file    //表示如果第四个字段包含abc,就打印整行

!~

不匹配,不精确比较

awk '$0 !~ /abc/' file      打印整条不包含abc的记录

&&

 和

awk '{if ( $1=="a" && $2=="b" ) print $0}' file    //如果第1、第2个字段值是a和b,打印整行

||

awk '{if ($1=="a" || $1=="b") print $0}' temp    //如果第1、第2个字段值是a或b,打印整行

 >

 大于

awk '$1>500 {print $2}' file     //如果字段1的值大于500,则打印字段2

>=

大于等于

awk '$1>=400 {print $2}' file     //如果字段1的值大于等于400,则打印字段2

<

小于

awk '$1<200 {print $2}' file     //如果字段1的值小于200,则打印字段2

<=

小于等于

awk '$1<=100 {print $2}' file     //如果字段1的值小于等于100,则打印字段2

+

awk '{print $3+10}' file    //字段3数值加10

-

awk '{print $3-10}' file    //字段3数值减10

*

awk '{print $3*10}' file    //字段3数值乘10

/

awk '{print $3/10}' file    //字段3数值除10

 

2、字符匹配代码块

awk [-F|-f|-v] ‘BEGIN{} // {command1; command2} END{}’ file

 

①字符匹配代码支持针对字符串的操作符

需要注意的是,不支持部分针对数字的操作符

如 awk '$3>/200/ {print $1}' baidu.log 中 $3>/200/ 实际没有生效,不管条件结果如何都会被忽略,直接print $1

②字符匹配代码块 // 中支持正则表达式

  

3、if语句

①必须用在{}中,且比较内容用()扩起来,支持if else

awk -F: '{if($1~/abc/) print $1}' file     //简写

awk -F: '{if($1~/abc/) {print $1}}'  file    //全写

awk -F: '{if($1~/abc/) {print $1} else {print $2}}' file    //if...else...

②有时不用if语句也可以实现同样效果图,如

awk -F: '{if($1~/abc/) {print $1}}' file    //$1为指定内容才显示

awk -F: '$1~/abc/ {print $1}' file    //与上面相同效果,没有用if语句,条件写在‘’外

    

4、while语句

与其他语言的while语句类似,条件为True时执行循环语句,False时不执行。

 

 

 

 

 

以下知识尚未整理验证

 

数组

netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) print i,"\t",a[i]}'

netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) printf "%-20s %-10s %-5s \n", i,"\t",a[i]}'

9523                               1     

9929                               1     

LISTEN                            6     

7903                               1     

3038/cupsd                   1     

7913                               1     

10837                             1     

9833                               1     

 

应用1

awk -F: '{print NF}' helloworld.sh                                                       //输出文件每行有多少字段

awk -F: '{print $1,$2,$3,$4,$5}' helloworld.sh                                 //输出前5个字段

awk -F: '{print $1,$2,$3,$4,$5}' OFS='\t' helloworld.sh                 //输出前5个字段并使用制表符分隔输出

awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS='\t' helloworld.sh           //制表符分隔输出前5个字段,并打印行号

 

应用2

awk -F'[:#]' '{print NF}'  helloworld.sh                                                  //指定多个分隔符: #,输出每行多少字段

awk -F'[:#]' '{print $1,$2,$3,$4,$5,$6,$7}' OFS='\t' helloworld.sh   //制表符分隔输出多字段

 

应用3

awk -F'[:#/]' '{print NF}' helloworld.sh                                               //指定三个分隔符,并输出每行字段数

awk -F'[:#/]' '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}' helloworld.sh     //制表符分隔输出多字段

 

应用4

计算/home目录下,普通文件的大小,使用KB作为单位

ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",sum/1024,"KB"}'

ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",int(sum/1024),"KB"}'         //int是取整的意思

 

应用5

统计netstat -anp 状态为LISTEN和CONNECT的连接数量分别是多少

netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s \n", i," ",sum[i]}'

 

应用6

统计/home目录下不同用户的普通文件的总数是多少?

ls -l|awk 'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s \n",i," ",sum[i]}'   

mysql        199 

root           374 

统计/home目录下不同用户的普通文件的大小总size是多少?

ls -l|awk 'NR!=1 && !/^d/{sum[$3]+=$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s \n",i," ",sum[i]/1024/1024,"MB"}'

 

应用7

输出成绩表

awk 'BEGIN{math=0;eng=0;com=0;printf "Lineno.   Name    No.    Math   English   Computer    Total\n";printf "------------------------------------------------------------\n"}{math+=$3; eng+=$4; com+=$5;printf "%-8s %-7s %-7s %-7s %-9s %-10s %-7s \n",NR,$1,$2,$3,$4,$5,$3+$4+$5} END{printf "------------------------------------------------------------\n";printf "%-24s %-7s %-9s %-20s \n","Total:",math,eng,com;printf "%-24s %-7s %-9s %-20s \n","Avg:",math/NR,eng/NR,com/NR}' test0

 

[root@localhost home]# cat test0 

Marry   2143 78 84 77

Jack    2321 66 78 45

Tom     2122 48 77 71

Mike    2537 87 97 95

Bob     2415 40 57 62

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值