linux下awk的基本使用

核心
1、什么是awk
2、awk的工作原理
3、awk的选项介绍
4、基本使用
5、运算符
6、内建变量
7、案例

1、什么是awk
AWK是一种处理文本文件的语言,是一个强大的文本分析工具。
之所以叫AWK是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符。

2、awk的工作原理
awk ‘BEGIN{ commands } pattern{ commands } END{ commands }’
第一步:执行BEGIN{ commands }语句块中的语句;
第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END{ commands }语句块。 BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。 END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块。

3、awk的选项介绍
awk的语法格式

awk [选项参数] ‘script’ var=value file(s)

awk [选项参数] -f scriptfile var=value file(s)

选项参数说明

1、 -F fs or –field-separator fs

指定输入文件拆分隔符,fs是一个字符串或者一个正则表达式 如-F: 表示按照:字符来做分隔

2、-v val=value or –asign var=value

赋值一个用户自定义变量,Linux我们一般是用${val}来使用一个变量但是awk不行,需要用-v来赋值

3、-f scriptfile or –file scriptfile

从脚本文件中读取awk命令

4、-mf nnn and -mr nnn

对nnn值设置内在限制,-mf 选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目,这2个功能是bell
实验室版awk的扩展功能,在标准awk中不适用

5、-W compact or –compat,-W traditional or –traditional

在兼容模式下运行awk,所以gawk的行为和标准的awk一样,所有的awk扩展都被忽略

6、-W copylefe or –copyleft ,-W copyright or –copyright

打印简短的版权信息

7、 -W help or –help ,-W usage or –usage

打印全部awk选项和每个选项的简短说明

8、-W lint or –lint

打印不能向传统unix平台移植的结构的告警

9、-W lint-old or –lint-old

打印关于不能向传统unix平台移植的结构的告警

10、-W posix

打开兼容模式,但是有以下限制,不识别:/x、函数关键字、
func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;
操作符**和**=不能替代^和^=;fflush无效

11、-W re-interval or –re-inerval

允许间隔正则表达式的使用, 如括号表达式 [[:alpha:]]

12、-W source program-text or –source program-text

使用program-text 作为源代码,可与-f 命令混用

13 -W version or –version

打印信息版本

4、基本使用
log.txt文本内容如下:
bigdata hadoop spark storm
java scala c C++
shell python,cpython,Ppython,jpython

用法一:
awk ‘{[pattern] action}’ {filenames} # 行匹配语句 awk ” 只能用单引号

实例
按照空格或者tab键做分隔,输出第一列和第4列的值 。这里awk的默认分隔符就是空格,所以我们没有必要指定

[root@SZB-L0032013 awk]# awk '{print $1,$4}' log.txt 
bigdata storm
java C++
shell
输出格式化
[root@SZB-L0032013 awk]# awk '{printf "%-8s %-10s\n",$1,$4}' log.txt 
bigdata  storm     
java     C++       
shell    

用法二:
awk -F #-F相当于内置变量FS, 指定分割字符

#使用","做分隔符
[root@SZB-L0032013 awk]# awk -F, '{print $1,$2}' log.txt 
bigdata hadoop spark storm 
java scala c C++ 
shell python cpython
# 或者使用内建变量,这里的BEGIN需要大写
[root@SZB-L0032013 awk]# awk 'BEGIN{FS=","} {print $1,$2} ' log.txt 
bigdata hadoop spark storm 
java scala c C++ 
shell python cpython

# 使用多个分隔符.先使用空格分割,然后对分割结果再使用”,”分割

[root@SZB-L0032013 awk]# awk -F '[ ,]' '{print $1,$2,$5}' log.txt 
bigdata hadoop 
java scala 
shell python jpython

用法三:
awk -v #设置变量

[root@SZB-L0032013 awk]# awk -v a=1 '{print a+1,$1}' log.txt 
2 bigdata
2 java
2 shell
[root@SZB-L0032013 awk]# awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt 
bigdata 1 bigdatas
java 1 javas
shell 1 shells

用法四
awk -f {awk脚本} {文件名}

$ awk -f cal.awk log.txt
[root@SZB-L0032013 awk]# cat awk.file 
#!/bin/awk -f 
-F " " {print $1}
[root@SZB-L0032013 awk]# awk -f awk.file log.txt 
bigdata
java
shell

5、运算符

= += -= *= /= %= ^= **=     赋值
?:                                   C条件表达式
||                          逻辑或
&&                          逻辑与
~ ~!                        匹配正则表达式和不匹配正则表达式
< <= > >= != ==             关系运算符
空格                        连接
+ -                         加,减
* / %                         乘,除与求余
+ - !                         一元加,减和逻辑非
^ ***                         求幂
++ --                         增加或减少,作为前缀或后缀
$                            字段引用
in                          数组成员

案例

[root@SZB-L0032013 awk]# awk '{print $1}' log.txt 
bigdata
java
shell
[root@SZB-L0032013 awk]# awk '$1=="shell" || $1=="java" {print $1}' log.txt 
java
shell

[root@SZB-L0032013 awk]# awk '{print $1}' log.txt 
bigdata
java
shell
[root@SZB-L0032013 awk]# awk '$1>"c" {print $1}' log.txt 
java
shell

注意:> < 可以作为字符串比较,也可以用作数值比较,关键看操作数如果是字符串就会转换为字符串比较。两个都为数字才转为数值比较。字符串比较:按照ASCII码顺序比较。

[root@SZB-L0032013 awk]# awk 'BEGIN{a="b";print a=="b"? "true":"false";}'
true
[root@SZB-L0032013 awk]# awk 'BEGIN{a="b";arr[0]="a";arr[1]="c";print(a in arr)}'
0
[root@SZB-L0032013 awk]# awk 'BEGIN{a="b";arr[0]="b";arr["b"]="c";print(a in arr)}'
1

正则表达式,第一列中包含big单词的行,打印出第一列和第二列
~ 表示匹配模式的开始 //表示需要匹配的模式

[root@SZB-L0032013 awk]# awk '$1 ~ /big/ {print $1,$2}' log.txt 
bigdata hadoop
[root@SZB-L0032013 awk]# cat log.txt 
bigdata hadoop spark storm
java scala c C++
shell python,cpython,Ppython,jpython 
#匹配包含有shell的行,相当于 grep
[root@SZB-L0032013 awk]# awk '/shell/' log.txt 
shell python,cpython,Ppython,jpython 
#模式取反操作
[root@SZB-L0032013 awk]# awk  ' !/hadoop/' log.txt 
java scala c C++
shell python,cpython,Ppython,jpython 
Hadoop drill hive
[root@SZB-L0032013 awk]# awk '$1 !~ /big/ {print $1,$2}' log.txt 
java scala
shell python,cpython,Ppython,jpython
Hadoop drill

6、内建变量

\$n                        当前记录的第n个字段,字段间由FS分隔
\$0                        完整的输入记录
ARGC                    命令行参数的数目
ARGIND              命令行中当前文件的位置(从0开始算)
ARGV                    包含命令行参数的数组
CONVFMT             数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO                   最后一个系统错误的描述
FIELDWIDTHS     字段宽度列表(用空格键分隔)
FILENAME            当前文件名
FNR                     同NR,但相对于当前文件
FS                      字段分隔符(默认是任何空格)
IGNORECASE      如果为真,则进行忽略大小写的匹配
NF                      当前记录中的字段数
NR                      当前记录数
OFMT                    数字的输出格式(默认值是%.6g)
OFS                     输出字段分隔符(默认值是一个空格)
ORS                     输出记录分隔符(默认值是一个换行符)
RLENGTH             由match函数所匹配的字符串的长度
RS                      记录分隔符(默认是一个换行符)
RSTART              由match函数所匹配的字符串的第一个位置
SUBSEP              数组下标分隔符(默认值是/034)
[root@SZB-L0032013 awk]# awk 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s\n","FILENAME","FNR","FS","NF","NR","ARGC","ARGIND\n";printf "-------------------------------------------------\n"}{printf "%4s %4s %4s %4s %4s %4s %4s\n",FILENAME,FNR,FS,NF,NR,ARGC,ARGIND}' log.txt 
FILENAME  FNR   FS   NF   NR ARGC ARGIND

-------------------------------------------------
log.txt    1         4    1    2    1
log.txt    2         4    2    2    1
log.txt    3         2    3    2    1
[root@SZB-L0032013 awk]# awk -F "=" 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s\n","FILENAME","FNR","FS","NF","NR","ARGC","ARGIND\n";printf "-------------------------------------------------\n"}{printf "%4s %4s %4s %4s %4s %4s %4s\n",FILENAME,FNR,FS,NF,NR,ARGC,ARGIND}' log.txt 
FILENAME  FNR   FS   NF   NR ARGC ARGIND

-------------------------------------------------
log.txt    1    =    1    1    2    1
log.txt    2    =    1    2    2    1
log.txt    3    =    1    3    2    1
[root@SZB-L0032013 awk]# awk '{print NR,FNR,$1,$2,$3}' log.txt 
1 1 bigdata hadoop spark
2 2 java scala c
3 3 shell python,cpython,Ppython,jpython
[root@SZB-L0032013 awk]# awk '{print NR,FNR,$1,$2,$3}' OFS="$" log.txt 
1$1$bigdata$hadoop$spark
2$2$java$scala$c
3$3$shell$python,cpython,Ppython,jpython
忽略大小写匹配
[root@SZB-L0032013 awk]# awk 'BEGIN{IGNORECASE=1} /hadoop/' log.txt 
bigdata hadoop spark storm
Hadoop drill hive
[root@SZB-L0032013 awk]# awk  '/hadoop/' log.txt 
bigdata hadoop spark storm

7、案例
有一个文件 sorce.txt里面是各个同学的分数信息,现在需要统计每个同学的总成绩和平均成绩

[root@SZB-L0032013 awk]# cat sorce.txt 
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

[root@SZB-L0032013 awk]# cat awk.file 
#!/bin/awk -f
#BEGIN
BEGIN{
FS=" "
math=0
english=0
computer=0
printf "NAME   NO.   MATH   ENGLISH   COMPUTER   TOTAL\n"
printf "-----------------------------------------------\n"
}
#cal
{
math+=$3
english+=$4
computer+=$5
printf "%-6s %-4s %8d %8d %8d %8d\n",$1,$2, $3,$4,$5, $3+$4+$5
}
#END
END{
printf "-----------------------------------------------\n"
printf "TOTAL: 10%d %8d %8d \n",math,english,computer
printf "AVG: 10.2%d %8.2d %8.2d\n",math/NR,english/NR,computer/NR
}

运行的结果是
[root@SZB-L0032013 awk]# awk -f awk.file sorce.txt 
NAME   NO.   MATH   ENGLISH   COMPUTER   TOTAL
-----------------------------------------------
Marry  2143       78       84       77      239
Jack   2321       66       78       45      189
Tom    2122       48       77       71      196
Mike   2537       87       97       95      279
Bob    2415       40       57       62      159
-----------------------------------------------
TOTAL: 10319      393      350 
AVG: 10.263       78       70

其他的案例
统计一个目录下面文件的总大小

[root@SZB-L0032013 ProCAppnt]# ls -l *.txt|awk 'BEGIN{FS=" "} {sum+=$5} END{print sum/1024/1024"MB"}'
1032.93MB

统计行长度大于20的记录

[root@SZB-L0032013 awk]# awk 'length>20' log.txt 
bigdata hadoop spark storm
shell python,cpython,Ppython,jpython
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值