awk 报告生成器

linux中文本处理三剑客:

grep:文本过滤器,根据匹配模式,显示匹配到的行 egrep==grep -E

sed:流编辑器

awk:是个报告生成器,也是文本处理工具。从文本中抽取符合条件的数据并以特定的格式显示出来。linux中的awk,GNU-awk==gawk


语法结构:

awk [option] 'PATTERN{ACTION}' file1 file2...

PATTERN:模式;是指定的抽取文件数据的条件。

ACTION:要对匹配的数据进行处理的动作。

在awk中的行与列:

filed 字段(列)

record 记录(行)


awk的模式

awk 'PATTERN{action}' file...

PATTERN 模式

awk 'BEGIN{}{pattern}{ACTION}{END}' file1,file2...

BEGIN和END只输入或输出一次

其他的每次都要执行

例
1、regexp 正则表达式
[root@localhost ~]# awk -F: '/^ro/{print $1}' /etc/passwd	整条数据和ro比较
2、表达式
[root@localhost ~]# awk -F: '$3>500{print $1}' /etc/passwd
[root@localhost ~]# awk -F: '$1~/^a/{print $1}' /etc/passwd	字段一和a比较
(NF,取最后一个字段)
[root@localhost ~]# awk -F: '$NF~/bash$/{print $1}' /etc/passwd 
root
redhat
a
haha
1
[root@localhost ~]# awk -F: '$NF~/bash$/ && $1~/^ro/{print $1}' /etc/passwd
root
3、指定范围
从模式一到模式二	(模式一,模式二)取得是一个范围
[root@localhost ~]# awk -F: '$3==0,$7~/nologin$/{print $1}' /etc/passwd
root
bin
[root@localhost ~]# awk -F: '$1~/^s/,$7~/nologin$/{print $1}' /etc/passwd
字段一以s开头,字段七以nologin结尾
4、BEGIN/END 特殊的模式
[root@localhost ~]# awk -F: '$3==0,$7~/bash$/{print $1}END{print "end"}' /etc/passwd
root
end

$0 打印全部字段

$1 只打印第一片的字段 默认分隔符为空格

$2 只打印第二片的字段

例1
[root@localhost ~]# cat a
hello
my
name
is
huahua
[root@localhost ~]# awk '{print $0}' a
hello
my
name
is
huahua

-F:指定输入分隔符

例2
[root@localhost ~]# awk -F: '{print $1,$2}' /etc/passwd	//指定分隔符为符号
root x
bin x
daemon x

awk的变量

内置变量:

FS:field separator 读取文本时,所使用的分隔符,与-F一样 列分隔符

RS:record separator 输入文本信息所使用的行分隔符 行分隔符

OFS:output field separator 输出分隔符 列分隔符

ORS:output row separator 输出信息所使用的行分隔符 行分隔符

----------BEGIN可以指定多个选项,通过分号隔开

例3
[root@localhost ~]# awk -F: 'BEGIN{OFS="@"}{print $1,$2,$3}' /etc/passwd
root@x@0									//指定输出分隔符为@
bin@x@1
daemon@x@2

[root@localhost ~]# awk -F: 'BEGIN{OFS="@"}{ORS="<==>"}{print $1,$2,$3}' /etc/passwd
root@x@0<==>bin@x@1<==>daemon@x@2<==>a	//行分隔符为“<==>”

[root@localhost ~]# cat b
haha:
hei$:
lala:123
[root@localhost ~]# awk 'BEGIN{RS=":"}{print $1}' b
haha
hei$
lala
123

FNR和NR(行号相关)

FNR表示该记录在其对应文件中的行号, NR表示该记录在整个input stream中的行号。

如果只有一个文件,两者是一样的。如果是多个文件,则每读取一个新的文件时,FNR都会被重置为1,而NR一直增加。

例4
[root@localhost ~]# awk '{print FNR,$0}' a b
1 hello
2 my
3 name
4 is
5 huahua
1 haha:
2 hei$:
3 lala:123
[root@localhost ~]# awk '{print NR,$0}' a b
1 hello
2 my
3 name
4 is
5 huahua
6 haha:
7 hei$:
8 lala:123

NF(列号相关)

NF:当前行一共有多少列,而非列号

$(NF-1) 取得是倒数第二个字段(列)

例5
[root@localhost ~]# cat b
haha a b
hei c
la
[root@localhost ~]# awk '{print NF}' b
3
2
1
[root@localhost ~]# awk '{print $(NF-1),$NF}' b	//打印倒数第二列和最后一列
a b
hei c
la la

自定义变量:

gawk 变量名需要区分大小写

1、在脚本中赋值变量

awk 'BEGIN{var="hello world";print var}'

2、在命令行中赋值变量

awk -v var="hello world" 'BEGIN{print var}'


awk的数组

例
//打印数组a中的元素,里面存储的元素没有顺序
[root@localhost ~]# awk -F: 'BEGIN{a["mon"]=1;a["tus"]=2}END{for(i in a){print i,a[i]}}' /etc/passwd
tus 2
mon 1
//统计每一种用户登录的bash
[root@localhost ~]# awk -F: '{shell[$NF]++}END{for(i in shell)print i,shell[i]}' /etc/passwd
/bin/sync 1
/bin/bash 5
/sbin/nologin 44
/sbin/halt 1
/sbin/shutdown 1
//分类统计网络系统的状态信息
[root@localhost ~]# netstat -an | awk '/^tcp/{hosts[$6]++}END{for(i in hosts){print i,hosts[i]}}'
LISTEN 13
ESTABLISHED 3

ARGV 保存命令行本身字符串

ARGC awk的参数的个数

例6
[root@localhost ~]# cat b
haha a b
hei c
la
[root@localhost ~]# awk '{print $0;print ARGV[1]}' b
haha a b
b
hei c
b
la
b
[root@localhost ~]# awk '{print $0;print ARGV[0]}' b
haha a b
awk
hei c
awk
la
awk

END取最后面一个路径

FILENAME:awk所处理的文件的名称

ENVIRON:当前shell环境变量及其值的相关联数组

例7
[root@localhost ~]# awk 'END{print FILENAME}' /root/b /etc/passwd
/etc/passwd
[root@localhost ~]# awk '{print ENVIRON["HOME"]}' /root/b
/root
/root
/root
[root@localhost ~]# awk 'BEGIN{print ENVIRON["HOME"]}' /root/b
/root
//BEGIN语句只执行一遍

awk的输出

printf

默认不会打印换行\n

%c:显示字符的ASCII码

%d %i:十进制整数

%e %E:科学计数法

%f:显示浮点数

%s:显示字符串

%u:无符号整数

%%:显示%本身

修饰符:

N:显示的宽度

-:左对齐,默认是右对齐

+:显示数值符号

 例8
[root@localhost ~]# awk -F: 'BEGIN{printf "%6s %25s\n","UID","USERNAME"}{printf "%6s %25s\n",$3,$1}' /etc/passwd
   	UID                  USERNAME
     	0                      root
     	1                       bin
     	2                    daemon

右对齐输出系统中每个用户的UID

awk -F: '{printf "%5d\n",$3}' /etc/passwd

左对齐

awk -F: '{printf "%-5d\n",$3}' /etc/passwd


awk的操作符

1、算术操作符:

-X:负数

x^y:x的y次方

x**y:x的y次方

x*y:乘法

x/y

x+y

x-y

x%y:取余

2、数值操作符:

=:赋值

+=

-=

*=

/=

%=

^=

**=

++

--

3、布尔值:

x<y

x<=y

x>y

x>=y

x==y

x!=y

x~y:X是个字符串,Y是个匹配模式,若X被Y匹配到则为真 x~/^r/

x!~y

4、表达式之间的逻辑关系:

&&

||

!

5、条件表达式:

A=4

B=3

A>B? a is max:b is max


awk的操作(action)

1、if else语句

例9
//如果第三个字段为0输出admin,否则输出nomal
[root@localhost ~]# awk -F: '{if($3==0){print "admin"}else{print "nomal"}}' /etc/passwd
admin
nomal
nomal
//如果第一个字段以ro开头,就输出admin,否则输出nomal
[root@localhost ~]# awk -F: '{if($1~/^ro/){print "admin"}else{print "nomal"}}' /etc/passwd
admin
nomal
//count初值为0,统计/etc/passwd文件里第三个字段大于500的有多少个
[root@localhost ~]# awk -F: 'BEGIN{count=0}$3>500{count++}END{print count}' /etc/passwd
13
//也可以用如下方法给count赋值,结果不变
[root@localhost ~]# awk -F: -v count=0 '{if($3>500)count++}END{print count}' /etc/passwd
13
初始化脚本变量一般放在begin里面,-v一般引用定义的变量

2、while语句

while(condition){语句1,语句2...}

例10
//length是内置函数;从字段一到最后一个字段,如果哪个字段长度大于等于4,输出该字段
[root@localhost ~]# awk -F: '{i=1;while(i<=NF){if(length($i)>=4){print $i};i++}}' /etc/passwd
root
root
/root
/bin/bash

do while语句    至少执行一次
while语句    可能一次都不执行

3、for循环

例11
//输出第一到第三个字段
[root@localhost ~]# awk -F: '{for(i=1;i<=3;i++){print $i}}' /etc/passwd
root
x
0
//输出第一道第三个字段,输出格式不同
[root@localhost ~]# awk -F: '{for(i=1;i<=3;i++){printf "%s",$i};printf "\n"}' /etc/passwd
rootx0
binx1
//循环中可以根据自己的需求,加上break和continue语句,这里说一下next语句:
//next	提前结束对本行文本的处理
[root@localhost ~]# awk -F: '{if($3%2==1){next};print $1}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin

awk的内置函数

1、split()返回一个下标从零开始的一维数组,split函数包含指定数目的子字符串。

2、system(command) 执行系统命令

3、systime() 显示当前时间,返回的是时间戳

4、substr() 截取子字符串

例12
//1、查看当前在线客户端前10名
[root@localhost ~]# netstat -ant | awk '$1~/^tcp$/&&/:22/{split($5,clients,":");IPS[clients[1]]++}END{for(i in IPS){print IPS[i],i}}' | sort -nr | head -n 10
1 192.168.100.1
1 0.0.0.0
//2、返回的是执行状态码,因为我没有/tmp/ls.log文件,所以是标准错误
[root@localhost ~]# awk 'BEGIN{a=system("ls /tmp/ls.log&>/dev/null");print a}'
2
//3、1544626789是linux时间戳,单位是秒数
[root@localhost ~]# awk 'BEGIN{a=system("ls /tmp/ls.log&>/dev/null");print a;print systime()}'
2
1544626789		//linux时间戳,单位是秒数
//4、截取变量A里的第二个和第三个字符
[root@localhost ~]# awk 'BEGIN{A="tom is cat";b=substr(A,2,3);print b}'
om 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值