gawk 语法介绍及其实例

gawk 语法介绍及其实例 

§·awk介绍

Linux文本处理三剑客:grep  sed awk 。其中grep是一种文本过滤工具,sed是文本行编辑器,而awk是一种报表生成器,就是对文件进行格式化处理的,这里的格式化不是文件系统的格式化,而是对文件的内容进行的各种排版,进而格式化显示。

linux之上我们使用awkGUN awk简称gawk,并且gawk其实就是awk的连接文件,gawk是一种过程是编程语言,gawk还支持条件判断,数组,循环等各种编程语言中所有的可以使用的功能,因此我们还可以把gawk成为一种脚本语言解释器。

§·awk基本用法

※·基本用法:

awk [options] program  var=value  file

awk [options]   -f programfile  var=value   file

awk [options]   'BEGIN{ action;}  pattern { action;}  END{ action;}'   file …

#需要处理的文本每一行我们称之为 记录

#BEGIN{ action;}  处理记录前的需要执行的动作,比如:打印提示符等

#pattern { action;} 匹配时处理的动作

#END{ action;}   处理一条记录后需要执行的东西,比如:打印结束语,或求和,求积等等。

awk程序通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块,共3部分组成

program  通常是被单引号或双引号中的编程语言

pattern  模式

action;… : 动作语句,可以是由多个语句组成,各个语句使用分号分隔,如: print  printf

·选项:

-F 指明输入时用到的字段分隔符

-v  var=value:  自定义变量

※·基本格式:

awk   [options] 'program' file

·#[options]

-f /PATH/FROM/AWK_SCRIPT:指明后面需要运用的 awk脚本

-F :指明分隔符

-v :声明变量

program:pattern{action statements;..}

patternaction

pattern部分决定动作语句何时触发及触发事件

BEGIN,END

action  statements对数据进行处理,放在{}内指明

print, printf

分割符、域和记录

awk执行时,由分隔符分隔的字段(域)标记$1,$2..$n称为域标识。$0为所有域,注意:和shell中变量$符含义不同

•文件的每一行称为记录

•省略action,则默认执行print $0 的操作。

※·awk工作原理

·第一步:

执行 BEGIN{action;} 语句块中的语句

比如:
[root@centos68 ~]#  tail  -n5  /etc/passwd  |  awk 'BEGIN{FS=":";f=1}{print$f}'
#BEGIN{FS=”:”;f=1}  :  记录处理前,表明分隔符为: 变量f=1
#{print$f}  : 没有pattern表示每条记录都匹配,打印第一列
sshd
tcpdump
admin
chen
mockbuild
[root@centos68 ~]#

·第二步:

从文件或标准输入(stdin)读取一行,然后执行pattern{ action;}语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。

·第三步:

当读至输入流末尾时,执行END{action;}语句块

·BEGIN 语句块的作用

BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中

·END语句块的作用

END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块

·pattern语句块

pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块

 

※·print格式:print item1, item2, …

·要点:

(1) 逗号分隔符

(2) 输出的各item可以字符串,也可以是数值;当前记录的字段、变量或awk的表达式

(3) 如省略item,相当于print $0

·print格式示例:

awk  '{print "hello,awk"}'

[root@centos68 ~]# awk '{print "hello ,awk"}'   
#awk支持标准的输入,后面没有接文件或没有管道输入导入,就会出现交互式输入的情况
#输入一行,由于没有patterm,所以就匹配你所有的行,在打印 hello,awk 的估计字符串
1
hello ,awk
2
hello ,awk
3
hello ,awk
4
hello ,awk
5
hello ,awk
[root@centos68 ~]#

awk -F:  '{print "wang"}' /etc/issue

[root@centos68 ~]#  awk   -F:  '{print "wang"}'  /etc/issue
#处理/etc/issue的每一行,每一条记录处理完打印固定字符串 wang
wang
wang
wang
wang
wang
wang
wang
[root@centos68 ~]#

 

awk F: {print $1}/etc/passwd

[root@centos68 isolinux]# awk -F: '{print$1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
uucp
operator
games
gopher
ftp
nobody
dbus
usbmuxd
rpc
rtkit
avahi-autoipd
vcsa
abrt
rpcuser
nfsnobody
haldaemon
ntp
apache
saslauth
postfix
mysql
gdm
pulse
sshd
tcpdump
admin
chen
mockbuild

awk F: {print $0}/etc/passwd  #打印每一行

awkF: {print $1\t$3}/etc/passwd

[root@centos68 isolinux]# awk -F: '{print$1 "\t" $3}' /etc/passwd
#打印 /etc/passwd 的第1列和第3列的并且以tab键分隔
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
uucp 10
operator 11
games 12
gopher 13
ftp 14
nobody 99
dbus 81
usbmuxd 113
rpc 32
rtkit 499
avahi-autoipd 170
vcsa 69
abrt 173
rpcuser 29
nfsnobody 65534
haldaemon 68
ntp 38
apache 48
saslauth 498
postfix 89
mysql 27
gdm 42
pulse 497
sshd 74
tcpdump 72
admin 500
chen 501
mockbuild 502
[root@centos68 isolinux]#

tail 3  /etc/fstab | awk {print $2,$4}

[root@centos68 isolinux]# tail -n3 /etc/fstab | awk '{print $2"\t" $4}'
/sys defaults
/proc defaults
/mnt/sda6 defaults,usrquota,grpquota
[root@centos68 isolinux]#

§·awk变量

※·awk内建变量

FS输入字段分隔符,默认为空白字符

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

awk F:   '{print $1,$3,$7}   /etc/passwd

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

 tail -n3 /etc/fstab | awk -v OFS='—–' '{print $1,$2}'

[root@centos68 isolinux]# tail -n3 /etc/fstab | awk -v OFS='-----' '{print $1,$2}'
sysfs-----/sys
proc-----/proc
/dev/sda6-----/mnt/sda6

 

RS输入记录分隔符,指定输入时的换行符,原换行符仍有效

tail -n1 /etc/passwd | awk -F: -v RS=':' '{print$1"—"}'

[root@centos68 ~]# tail -n1 /etc/passwd
mockbuild:x:502:502::/home/mockbuild:/bin/bash

 

[root@centos68 ~]# tail -n1 /etc/passwd | awk -F: -v RS=':' '{print$1"---"}'
mockbuild---
x---
502---
502---
---
/home/mockbuild---
/bin/bash
---
[root@centos68 ~]# 
#从awk的结果来开看,RS的作用会把 一条记录中的 : 做为行结尾符,只要出现了 : 就会换行,在把每一行保存在变量$1中。

 

ORS输出记录分隔符,输出时用指定符号代替换行符

awk-v RS=' ' -v ORS='###'{print }/etc/passwd

[root@centos68 ~]# tail -n3 /etc/passwd | awk -F: -v ORS='#####' '{print$1,$3}'
admin 500#####chen 501#####mockbuild 502#####[root@centos68 ~]#

NF字段数量

Awk   -F:‘{print NF}/etc/fstab,  引用内置变量不用$

Awk   -F: '{print $(NF-1)}' /etc/passwd

[root@centos68 ~]# tail -n3 /etc/passwd | awk -F: '{print NF}'
7
7
7
[root@centos68 ~]# tail -n3 /etc/passwd | awk -F: '{print $(NF-1)}'
/home/admin
/home/chen
/home/mockbuild
[root@centos68 ~]#

NR行号

awk '{print NR}' /etc/fstab; awk END'{print NR}' /etc/fstab

[root@centos68 ~]# tail -n3 /etc/passwd | awk -F: '{print NR"\t" $0}'
1 admin:x:500:500:chenjiashun:/home/admin:/bin/bash
2 chen:x:501:501::/home/chen:/bin/bash
3 mockbuild:x:502:502::/home/mockbuild:/bin/bash
[root@centos68 ~]# tail -n3 /etc/passwd | awk -F: 'END{print NR"\t" $0}'
3 mockbuild:x:502:502::/home/mockbuild:/bin/bash
[root@centos68 ~]# tail -n3 /etc/passwd | awk -F: 'BEGIN{print NR"\t" $0}'
0 
[root@centos68 ~]#

 

FNR:各文件分别计数,行号

awk  '{print FNR}' /etc/fstab /etc/inittab

#两个文件分别统计行号,并且只打印行号

FILENAME:当前文件名

awk   'END{print FILENAME}’  /etc/fstab

[root@centos68 ~]# awk  'END{print FILENAME}'  /etc/passwd   #处理完最后一样后,打印出文件的名称
/etc/passwd
[root@centos68 ~]#

ARGC:命令行参数的个数

awk   '{print ARGC}’       /etc/fstab /etc/inittab

awk BEGIN {print ARGC}/etc/fstab /etc/inittab

[root@centos68 ~]# awk 'BEGIN{print ARGC}' /etc/issue
2
[root@centos68 ~]# awk '{print ARGC}' /etc/issue
2
2
2
2
2
2
2
[root@centos68 ~]# awk '{print ARGC}' /etc/issue /etc/issue
3
3
3
3
3
3
3
3
3
3
3
3
3
3
[root@centos68 ~]#

ARGV:数组,保存的是命令行所给定的各参数

awk BEGIN {print ARGV[0]}/etc/fstab /etc/inittab

awk BEGIN {print ARGV[1]}/etc/fstab /etc/inittab

[root@centos68 ~]# awk 'BEGIN{print ARGV[0]}' /etc/{fstab,passwd}
awk
[root@centos68 ~]# awk 'BEGIN{print ARGV[1]}' /etc/{fstab,passwd}
/etc/fstab
[root@centos68 ~]# awk 'BEGIN{print ARGV[2]}' /etc/{fstab,passwd}
/etc/passwd
[root@centos68 ~]# awk 'BEGIN{print ARGV[3]}' /etc/{fstab,passwd}
 
[root@centos68 ~]# awk 'BEGIN{print ARGC}' /etc/{fstab,passwd}
3
[root@centos68 ~]#

※·自定义变量

(1) -v var=value

变量名区分字符大小写

(2) program中直接定义

v示例:

awk   -v test='hello gawk'   '{print test}' /etc/fstab

awk  -v test='hello gawk'   'BEGIN{print test}'

awk  'BEGIN{test="hello,gawk";print test}'

[root@centos68 ~]# awk   -v   test='helol gawk'  'BEGIN{print test}' /etc/fstab
helol gawk
[root@centos68 ~]# awk   -v   test='helol gawk'  'END{print test}'   /etc/fstab
helol gawk
[root@centos68 ~]# awk   -v   test='helol gawk'  '{print test}'   /etc/issue
helol gawk
helol gawk
helol gawk
helol gawk
helol gawk
helol gawk
helol gawk
[root@centos68 ~]# awk   'BEGIN{test="helol,gawk "; print test}'   /etc/issue
helol,gawk 
[root@centos68 ~]#

§·awk格式化

※·printf命令

◎·格式化输出:

printfFORMAT, item1, item2, …

(1) 必须指定FORMAT

(2) 不会自动换行,需要显式给出换行控制符,\n

(3) FORMAT中需要分别为后面每个item指定格式符

◎·格式符:

item一一对应

%c: 显示字符的ASCII

%d, %i: 显示十进制整数

%e, %E:显示科学计数法数值

%f:显示为浮点数

%g, %G:以科学计数法或浮点形式显示数值

%s:显示字符串

%u:无符号整数

%%: 显示%自身

◎·修饰符:

#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f

-: 左对齐(默认右对齐)%-15s

+:显示数值的正负符号%+d

※·printf示例

awk -F: {printf "%s",$1}/etc/passwd

[root@centos68 ~]# tail -n5 /etc/passwd |  awk -F:  '{printf "%s",$1}'
#printf默认是不会换行的,及打出来的一行字符串
sshdtcpdumpadminchenmockbuild[root@centos68 ~]# tail -n5 /etc/passwd | awk -F: '{printf "%s\n",$1}'
#%s表示的$1的类型为字符串类型
sshd
tcpdump
admin
chen
mockbuild
[root@centos68 ~]#

awk -F: {printf "%s\n",$1}/etc/passwd

[root@centos68 ~]# tail -n5 /etc/passwd |  awk -F:  '{printf "%s",$1}'
#printf默认是不会换行的,及打出来的一行字符串
sshdtcpdumpadminchenmockbuild[root@centos68 ~]# tail -n5 /etc/passwd | awk -F: '{printf "%s\n",$1}'
#%s表示的$1的类型为字符串类型
sshd
tcpdump
admin
chen
mockbuild
[root@centos68 ~]#

awk -F: {printf "Username: %s, UID%d\n",$1,$3}/etc/passwd

[root@centos68 ~]# tail -n5 /etc/passwd|  awk  -F:  '{printf "Username=%s----UID=%d\n",$1,$3}' 
Username=sshd----UID=74
Username=tcpdump----UID=72
Username=admin----UID=500
Username=chen----UID=501
Username=mockbuild----UID=502
[root@centos68 ~]#

awk -F: {printf "Username: %-15s, UID%d\n",$1,$3}/etc/passwd

[root@centos68 ~]# tail -n5 /etc/passwd| awk -F: '{printf "Username:%15s UID=%d\n",$1,$3}' 
Username:           sshd UID=74
Username:        tcpdump UID=72
Username:          admin UID=500
Username:           chen UID=501
Username:      mockbuild UID=502
[root@centos68 ~]# tail -n5 /etc/passwd| awk -F: '{printf "Username:%-10s UID=%d\n",$1,$3}' 
#  %-10s   表示为 $1字段控制在10个字符串内,左对齐,默认为右对齐
#  %d\n    表示为$3为数字类型,并且尾部换行
Username:sshd       UID=74
Username:tcpdump    UID=72
Username:admin      UID=500
Username:chen       UID=501
Username:mockbuild  UID=502

tail -n5 /etc/passwd| awk -F: '{printf "Username:%-10s UID=%-10d Shell=%s\n",$1,$3,$NF}'

[root@centos68 ~]# tail -n5 /etc/passwd| awk -F: '{printf "Username:%-10s UID=%-10d Shell=%s\n",$1,$3,$NF}' 
#Username:%-10s :$1 字符串类型10个字符内左对齐
#UID=%-10d  :  $3 数字类型5个左对齐
#Shell=%s\n"  : $NF 最后一个分段字符串类型 换行
Username:sshd       UID=74         Shell=/sbin/nologin
Username:tcpdump    UID=72         Shell=/sbin/nologin
Username:admin      UID=500        Shell=/bin/bash
Username:chen       UID=501        Shell=/bin/bash
Username:mockbuild  UID=502        Shell=/bin/bash
[root@centos68 ~]#

§·awk操作符

◎·算术操作符:

x+y, x-y, x*y, x/y, x^y, x%y

-x: 转换为负数

+x: 转换为数值

◎·字符串操作符:

没有符号的操作符,字符串连接

◎·赋值操作符:

=, +=, -=, *=, /=, %=, ^=

++, —

◎·比较操作符:

>, >=, <, <=, !=, ==

◎·模式匹配符:

~:左边是否和右边匹配包含

!~:是否不匹配

cat /etc/passwd|awk'$0 ~ /root/'|wc-l

cat /etc/passwd|awk'$0 !~ /root/'|wc-l

[root@centos68 ~]# cat /etc/issue  #issue文件内容
CentOS release 6.8 (Final)
Kernel \r on an \m
 
==============================
Welcome to my hostname SA!
Welcome to my hostname SC
==============================
[root@centos68 ~]# cat /etc/issue | awk '$0~/hostname/{print}'  #显示包含 hostname 的行
Welcome to my hostname SA!
Welcome to my hostname SC
[root@centos68 ~]# cat /etc/issue | awk '$0!~/hostname/{print}'  #显示不包含 hostname 的行
CentOS release 6.8 (Final)
Kernel \r on an \m
 
==============================
==============================

 

◎·逻辑操作符:

&&||!

v示例:

awk -F: '$3>=0&&$3<=10{print "UID="$3"\t\t""username="$1}' /etc/passwd

[root@centos68 ~]# awk  -F:  '$3>=0&&$3<=10{print "UID="$3 "\t\t" "username=" $1}'  /etc/passwd
#当$3 大于等于0时,并且小于10时,打印$1  与 $3
UID=0  username=root
UID=1  username=bin
UID=2  username=daemon
UID=3  username=adm
UID=4  username=lp
UID=5  username=sync
UID=6  username=shutdown
UID=7  username=halt
UID=8  username=mail
UID=10  username=uucp
[root@centos68 ~]#

awk -F: '$3==0 || $3>=500{printf "UID=%-7d username=%-10s\n",$3,$1}' /etc/passwd

[root@centos68 ~]# awk -F: '$3==0 || $3>=500{printf "UID=%-7d username=%-10s\n",$3,$1}' /etc/passwd
#当$3等于0或者$3大于等于500,按格式打印$3 , 与$1
UID=0       username=root      
UID=65534   username=nfsnobody 
UID=500     username=admin     
UID=501     username=chen      
UID=502     username=mockbuild 
[root@centos68 ~]#

◎·函数调用:

function_name(argu1, argu2, …)

◎·条件表达式:

selector?if-true-expression:if-false-expression

#selector :  条件判断

#if-true-expression : 条件为真的时候

#if-false-expression : 条件为假的时候

•示例:

 awk -F: '{$3>=1000? usertype="CommonUser": usertype="SysadminorSysUser"; printf"%15s:%-s\n", $1,usertype}'  /etc/passwd

#判断 $3是否大于1000,如果大于1000usertype变量赋值为:CommonUser,如果小于等于1000 usertype变量赋值为:SysadminorSysUser

[root@~]# awk -F: '{$3>=1000?Usertype="CommonUser":Usertype="SystemUser";printf"Usertype=%-s:Username:%-15sUID=%-d\n",Usertype,$1,$3 }' /etc/passwd
Usertype=SystemUser:   Username:root             UID=0
Usertype=SystemUser:   Username:bin              UID=1
Usertype=SystemUser:   Username:daemon           UID=2
Usertype=SystemUser:   Username:adm              UID=3
Usertype=SystemUser:   Username:lp               UID=4
Usertype=SystemUser:   Username:sync             UID=5
Usertype=SystemUser:   Username:shutdown         UID=6
Usertype=SystemUser:   Username:halt             UID=7
Usertype=SystemUser:   Username:mail             UID=8
Usertype=SystemUser:   Username:uucp             UID=10
Usertype=SystemUser:   Username:operator         UID=11
Usertype=SystemUser:   Username:games            UID=12
Usertype=SystemUser:   Username:gopher           UID=13
Usertype=SystemUser:   Username:ftp              UID=14
Usertype=SystemUser:   Username:nobody           UID=99
Usertype=SystemUser:   Username:dbus             UID=81
Usertype=SystemUser:   Username:usbmuxd          UID=113
Usertype=SystemUser:   Username:rpc              UID=32
Usertype=SystemUser:   Username:rtkit            UID=499
Usertype=SystemUser:   Username:avahi-autoipd    UID=170
Usertype=SystemUser:   Username:vcsa             UID=69
Usertype=SystemUser:   Username:abrt             UID=173
Usertype=SystemUser:   Username:rpcuser          UID=29
Usertype=CommonUser:   Username:nfsnobody        UID=65534
Usertype=SystemUser:   Username:haldaemon        UID=68
Usertype=SystemUser:   Username:ntp              UID=38
Usertype=SystemUser:   Username:apache           UID=48
Usertype=SystemUser:   Username:saslauth         UID=498
Usertype=SystemUser:   Username:postfix          UID=89
Usertype=SystemUser:   Username:mysql            UID=27
Usertype=SystemUser:   Username:gdm              UID=42
Usertype=SystemUser:   Username:pulse            UID=497
Usertype=SystemUser:   Username:sshd             UID=74
Usertype=SystemUser:   Username:tcpdump          UID=72
Usertype=SystemUser:   Username:admin            UID=500
Usertype=SystemUser:   Username:chen             UID=501
Usertype=SystemUser:   Username:mockbuild        UID=502

◎·PATTERN:模式

·PATTERN:根据pattern条件,过滤匹配的行,再做处理

(1)如果未指定:空模式,匹配每一行

(2) /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来

awk'/^UUID/{print $1}' /etc/fstab

awk'!/^UUID/{print $1}' /etc/fstab

[root@centos68 ~]# awk '/^UUID/{print}' /etc/fstab  #显示以UUID开头的行
UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e /                       ext4    defaults        1 1
UUID=2c97fd2d-e455-493b-822c-25ce8c330e2b /boot                   ext4    defaults        1 2
UUID=1c6d09df-f7a1-4a72-b842-2b94063f38c7 /testdir                ext4    defaults        1 2
UUID=ebd1d743-af4a-465b-98a3-6c9d3945c1d7 swap                    swap    defaults        0 0
[root@centos68 ~]# awk '/UUID/{print}' /etc/fstab 
UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e /                       ext4    defaults        1 1
UUID=2c97fd2d-e455-493b-822c-25ce8c330e2b /boot                   ext4    defaults        1 2
UUID=1c6d09df-f7a1-4a72-b842-2b94063f38c7 /testdir                ext4    defaults        1 2
UUID=ebd1d743-af4a-465b-98a3-6c9d3945c1d7 swap                    swap    defaults        0 0

[root@centos68 ~]# awk '!/^UUID/{print}' /etc/fstab   #显示非UUID开头的行
 
#
# /etc/fstab
# Created by anaconda on Tue Jul 19 18:10:17 2016
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
/dev/sda6  /mnt/sda6  ext4 defaults,usrquota,grpquota 0 0
[root@centos68 ~]#

(3) relational expression: 关系表达式;结果有;结果为才会被处理;

·真:结果为非0值,非空字符串

·假:结果为空字符串

·示例:

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

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

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

•awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd

[root@centos68 ~]# awk -F: '$NF~"/bin/bash"{print$1,"\t",$NF}'  /etc/passwd
root   /bin/bash
mysql   /bin/bash
admin   /bin/bash
chen   /bin/bash
mockbuild   /bin/bash
[root@centos68 ~]# awk -F: '$NF~"bash$"{print$1,"\t",$NF}'  /etc/passwd
root   /bin/bash
mysql   /bin/bash
admin   /bin/bash
chen   /bin/bash
mockbuild   /bin/bash
[root@centos68 ~]#

•seq 10 | awk 'i=!i'

[root@centos68 ~]# seq 10 | awk 'i=!i{print}'
1
3
5
7
9
[root@centos68 ~]# seq 10 | awk 'i=!i'
1
3
5
7
9
[root@centos68 ~]#

(4) line ranges:行范围(在模式之间匹配,或通过NR变量来判断

startline,endline/pat1/,/pat2/不支持直接给出数字格式

awk-F: '/^root/,/^nobody/{print $1}' /etc/passwd

[root@centos68 ~]# awk -F: '/^bin/,/^mail/{print NR "\t" $1}' /etc/passwd
2 bin
3 daemon
4 adm
5 lp
6 sync
7 shutdown
8 halt
9 mail
[root@centos68 ~]#

awk-F: '(NR>=2&&NR<=10){print $1}' /etc/passwd

[root@centos68 ~]# awk -F: '(NR>=2&&NR<=9){print NR"\t" $1 }' /etc/passwd
2 bin
3 daemon
4 adm
5 lp
6 sync
7 shutdown
8 halt
9 mail
[root@centos68 ~]# awk -F: 'NR>=2&&NR<=10{print NR"\t" $1 }' /etc/passwd
2 bin
3 daemon
4 adm
5 lp
6 sync
7 shutdown
8 halt
9 mail
10 uucp

(5) BEGIN/END模式

BEGIN{}: 仅在开始处理文件中的文本之前执行一次

END{}:仅在文本处理完成之后执行一次

◎·PATTERN:模式事例

•awk  -F :  'BEGIN {print "USER USERID"} {print $1":"$3} END{print "end file"}'  /etc/passwd

[root@centos68 ~]# awk -F: 'BEGIN{print "USER \t USERID"}{print $1" \t "$3}END{print "end file"}' /etc/passwd
USER   USERID
root   0
bin   1
daemon   2
adm   3
lp   4
sync   5
shutdown   6
halt   7
mail   8
uucp   10
operator   11
games   12
gopher   13
ftp   14
nobody   99
dbus   81
usbmuxd   113
rpc   32
rtkit   499
avahi-autoipd   170
vcsa   69
abrt   173
rpcuser   29
nfsnobody   65534
haldaemon   68
ntp   38
apache   48
saslauth   498
postfix   89
mysql   27
gdm   42
pulse   497
sshd   74
tcpdump   72
admin   500
chen   501
mockbuild   502
end file
[root@centos68 ~]#

awk -F: 'BEGIN{print "USER \t USERID\n——————"}{print $1" \t "$3}END{print "===========\nend file"}' /etc/passwd

[root@centos68 ~]# awk -F: 'BEGIN{print "USER \t USERID\n------------------"}{print $1" \t "$3}END{print "===========\nend file"}' /etc/passwd
USER   USERID
------------------------
root   0
bin   1
daemon   2
adm   3
lp   4
sync   5
shutdown   6
halt   7
mail   8
uucp   10
operator   11
games   12
gopher   13
ftp   14
nobody   99
dbus   81
usbmuxd   113
rpc   32
rtkit   499
avahi-autoipd   170
vcsa   69
abrt   173
rpcuser   29
nfsnobody   65534
haldaemon   68
ntp   38
apache   48
saslauth   498
postfix   89
mysql   27
gdm   42
pulse   497
sshd   74
tcpdump   72
admin   500
chen   501
mockbuild   502
================================
end file
[root@centos68 ~]#

§·awk action (常用动作)

·常用的action分类

•(1) Expressions:算术,比较表达式等

•(2) Control  statementsif, while

•(3) Compound  statements:组合语句

•(4) input  statements

•(5) output  statementsprint

§·awk条件判断

※·awk控制语句

v { statements;} 组合语句

v if(condition) {statements;}

v if(condition) {statements;} else {statements;}

v while(conditon) {statments;}

v do {statements;} while(condition)

v for(expr1;expr2;expr3) {statements;}

v break

v continue

v delete array[index]

v delete array

v exit

※·awk控制语句if-else

语法:

if(condition) statement [else statement]

if(condition1){statement1}else if(condition2){statement 2}else{statement3}

v使用场景:对awk取得的整行或某个字段做条件判断

v示例:

awk -F:  '{if($3<=10)printf"Username=%-10s Uid=%d\n",$1,$3}' /etc/passwd

[root@centos68 ~]# awk -F:  '{if($3<=10)printf"Username=%-10s Uid=%d\n",$1,$3}' /etc/passwd
Username=root       Uid=0
Username=bin        Uid=1
Username=daemon     Uid=2
Username=adm        Uid=3
Username=lp         Uid=4
Username=sync       Uid=5
Username=shutdown   Uid=6
Username=halt       Uid=7
Username=mail       Uid=8
Username=uucp       Uid=10

 awk -F:  '{if($NF=="/bin/bash")print$1"\t" $NF}' /etc/passwd

[root@centos68 ~]# awk -F:  '{if($NF=="/bin/bash")print$1"\t" $NF}' /etc/passwd
root /bin/bash
mysql /bin/bash
admin /bin/bash
chen /bin/bash
mockbuild /bin/bash
[root@centos68 ~]#

awk  '{if(NF>6)print $0}' /etc/fstab

[root@centos68 ~]# awk  '{if(NF>6)print $0}' /etc/fstab 
# Created by anaconda on Tue Jul 19 18:10:17 2016
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
[root@centos68 ~]#

awk-F: '{if($3>=1000) {printf"Common user: %s\n",$1} else {printf"root or Sysuser: %s\n",$1}}' /etc/passwd

[root@centos68 ~]# awk  -F: '{if($3>=1000){printf"Common user:%s\n",$1}else{printf"root or Sysuser:%s\n",$1}}' /etc/passwd
root or Sysuser:root
root or Sysuser:bin
root or Sysuser:daemon
root or Sysuser:adm
root or Sysuser:lp
root or Sysuser:sync
root or Sysuser:shutdown
root or Sysuser:halt
root or Sysuser:mail
root or Sysuser:uucp
root or Sysuser:operator
root or Sysuser:games
root or Sysuser:gopher
root or Sysuser:ftp
root or Sysuser:nobody
root or Sysuser:dbus
root or Sysuser:usbmuxd
root or Sysuser:rpc
root or Sysuser:rtkit
root or Sysuser:avahi-autoipd
root or Sysuser:vcsa
root or Sysuser:abrt
root or Sysuser:rpcuser
Common user:nfsnobody
root or Sysuser:haldaemon
root or Sysuser:ntp
root or Sysuser:apache
root or Sysuser:saslauth
root or Sysuser:postfix
root or Sysuser:mysql
root or Sysuser:gdm
root or Sysuser:pulse
root or Sysuser:sshd
root or Sysuser:tcpdump
root or Sysuser:admin
root or Sysuser:chen
root or Sysuser:mockbuild
[root@centos68 ~]#

df -h|awk -F[%] '/^\/dev/{print $1} '|awk'{if($NF>=80) print $1}

[root@centos68 ~]# df -h | awk -F% '/^\/dev/{print $1}'  #找出%前面的行
/dev/sda2        48G   21G   25G  46
/dev/sda1       190M   60M  117M  34
/dev/sda3        20G  122M   18G   1
/dev/sda6       9.8G   23M  9.2G   1
/dev/sr0        3.7G  3.7G     0 100
[root@centos68 ~]# df -h | awk -F% '/^\/dev/{print $1}'| awk '{if($NF>=80)print $1}' #找出大于%80的行
/dev/sr0
[root@centos68 ~]#

awk'BEGIN{ test=100;if(test>90){ print "very good";}else if(test>60){ print "good";}else{ print "no pass";}}'

[root@centos68 ~]# awk -F: 'BEGIN{test=50;if(test>90){print"very good"}else if(test>60){print "good"}else{print"no pass"}}'
no pass
[root@centos68 ~]# awk -F: 'BEGIN{test=70;if(test>90){print"very good"}else if(test>60){print "good"}else{print"no pass"}}'
good
[root@centos68 ~]# awk -F: 'BEGIN{test=93;if(test>90){print"very good"}else if(test>60){print "good"}else{print"no pass"}}'
very good
[root@centos68 ~]#

※·awk控制语句 while循环

·while循环

·语法:while(condition) statement

条件“真”,进入循环;条件“假”,退出循环

·使用场景:

对一行内的多个字段逐一类似处理时使用

对数组中的各元素逐一处理时使用

·示例:length()求出该字段的长度 函数调用

awk  '/^UUID/{i=1;while(i<=NF){printf"%-50s %-5d\n",$i ,length($i);i++}}' /etc/fstab

#找出UUID开头的行,并且把每个字段分别统计字符个数

[root@centos68 ~]# awk  '/^UUID/{i=1;while(i<=NF){printf"%-50s %-5d\n",$i ,length($i);i++}}' /etc/fstab 
UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e          41   
/                                                  1    
ext4                                               4    
defaults                                           8    
1                                                  1    
1                                                  1    
UUID=2c97fd2d-e455-493b-822c-25ce8c330e2b          41   
/boot                                              5    
ext4                                               4    
defaults                                           8    
1                                                  1    
2                                                  1    
UUID=1c6d09df-f7a1-4a72-b842-2b94063f38c7          41   
/testdir                                           8    
ext4                                               4    
defaults                                           8    
1                                                  1    
2                                                  1    
UUID=ebd1d743-af4a-465b-98a3-6c9d3945c1d7          41   
swap                                               4    
swap                                               4    
defaults                                           8    
0                                                  1    
0                                                  1

awk  '/^UUID/{i=1;while(i<=NF){if(length($i)>=8){ printf"%-50s %-5d\n",$i ,length($i)};i++}}' /etc/fstab

#找出UUID开头的行,当字段数量大于8时,显示字段数和字符数量

[root@centos68 ~]# awk  '/^UUID/{i=1;while(i<=NF){if(length($i)>=8){ printf"%-50s %-5d\n",$i ,length($i)};i++}}' /etc/fstab 
UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e          41   
defaults                                           8    
UUID=2c97fd2d-e455-493b-822c-25ce8c330e2b          41   
defaults                                           8    
UUID=1c6d09df-f7a1-4a72-b842-2b94063f38c7          41   
/testdir                                           8    
defaults                                           8    
UUID=ebd1d743-af4a-465b-98a3-6c9d3945c1d7          41   
defaults                                           8    
[root@centos68 ~]#

※·awk控制语句 do ….. while循环

do-while循环

语法:do statement while(condition)

意义:无论真假,至少执行一次循环体

•示例:

awk 'BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}'

#while循序的不同之处在于,do先执行一次循序体,在通过while条件判断是否需不需要执行循环体

[root@centos68 ~]# awk  'BEGIN{total=0;i=0;do{total+=i;i++}while(i<=100);print total}'
5050
[root@centos68 ~]#

 

※·awk控制语句 for 循环

for循环

语法:for(expr1;expr2;expr3) statement

for(variable assignment;condition;iterationprocess) {for-body}

#for (变量赋值;判断条件;变量修正){循序体}

特殊用法:能够遍历数组中的元素;

语法:for(var  in array) {for-body}

示例:

awk  '/^UUID/{for(i=1;i<=NF;i++){if(length($i)>8){print $i,length($i)}}}' /etc/fstab

[root@centos68 ~]# awk  '/^UUID/{for(i=1;i<=NF;i++){if(length($i)>8){print $i,length($i)}}}' /etc/fstab 
UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e 41
UUID=2c97fd2d-e455-493b-822c-25ce8c330e2b 41
UUID=1c6d09df-f7a1-4a72-b842-2b94063f38c7 41
UUID=ebd1d743-af4a-465b-98a3-6c9d3945c1d7 41

 

※·性能比较

v#time (awk 'BEGIN{ total=0;for(i=0;i<=10000;i++){total+=i;};print total;}')

[root@centos68 ~]# time(awk 'BEGIN{total=0;for(i=0;i<=1000;i++){total+=i};print total}')
500500
 
real 0m0.018s
user 0m0.000s
sys 0m0.017s
[root@centos68 ~]#

v#time(total=0;for i in $(seq 10000);do total=$(($total+i));done;echo $total)

[root@centos68 ~]# time(total=0;for i in $(seq 10000);do total=$(($total+i));done ;echo $total)
50005000
 
real 0m0.091s
user 0m0.073s
sys 0m0.030s

※·awk控制语句 switch语句

•switch语句

语法:switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; …; default: statement}

•breakcontinuevbreak [n]vnextvcontinue [n]

 

vnext 提前结束对本行处理而直接进入下一行处理(awk自身循环)

 

•awk‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0){continue}sum+=i}print sum}‘

#统计1-100偶数的和
[root@Centos7 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0){continue}sum+=i};print sum}'
2500
#统计1-100奇数的和
[root@Centos7 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2!=0){continue}sum+=i};print sum}'
2550
[root@Centos7 ~]#

•awk‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==11){break}sum+=i}print sum}‘

#统计1-10的和

[root@Centos7 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==11){break}sum+=i};print sum}'
55
[root@Centos7 ~]#

•awk  -F: '{if($3%2!=0)next;printf"Username: %-15s Uid: %d\n",$1,$3}' /etc/passwd

#显示UID号为偶数的行

[root@Centos7 ~]# awk  -F: '{if($3%2!=0)next;printf"Username: %-15s Uid: %d\n",$1,$3}' /etc/passwd
Username: root            Uid: 0
Username: daemon          Uid: 2
Username: lp              Uid: 4
Username: shutdown        Uid: 6
Username: mail            Uid: 8
Username: games           Uid: 12
Username: ftp             Uid: 14
Username: systemd-network Uid: 998
Username: unbound         Uid: 996
Username: geoclue         Uid: 994
Username: rpc             Uid: 32
Username: rtkit           Uid: 172
Username: avahi-autoipd   Uid: 170
Username: setroubleshoot  Uid: 992
Username: nfsnobody       Uid: 65534
Username: libstoragemgmt  Uid: 990
Username: gdm             Uid: 42
Username: avahi           Uid: 70
Username: sshd            Uid: 74
Username: ntp             Uid: 38
Username: tcpdump         Uid: 72
Username: ChenJiaShun     Uid: 1000
Username: hacker          Uid: 1002

 

§·awk数组

◎·关联数组:array [index-expression]

◎·index-expression:

(1) 可使用任意字符串;字符串要使用双引号括起来

(2) 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”

•若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历

◎·示例:

weekdays[mon]="Monday

awk 'BEGIN{weekdays["mon"]="Monday";

weekdays["tue"]="Tuesday";print weekdays["mon"]}

awk '!a[$0]++{print NR , $1}' aaaa

#排除重复行
#分析 a[$0]默认情况下为空,空及为0,$0表示为整行,
#awk为行间自动循环,比如第一行为:a[a]=0(空), !a[a]=1(非空),非空就打印出 aaaa文件的整行及
   其行号 a[a]++及是,a[a]=2
#比如第二行为:a[b]=0(空), !a[b]=1(非空),非空就打印出 aaaa文件的整行;
#当遇到第7行 $0=b,时,a[$0]=1 , !a[$0]=0 ,不在打印,a[$0]++ , a[$0]=1.
[root@Centos7 ~]# awk '!a[$0]++{print NR , $1}' aaaa 
1 a
2 b
3 c
4 d
5 e
6 aa
9 ee
[root@Centos7 ~]# awk '{print NR , $1}' aaaa 
1 a
2 b
3 c
4 d
5 e
6 aa
7 d
8 c
9 ee
[root@Centos7 ~]#

 

◎·若要遍历数组中的每个元素,要使用for循环

◎·for(varin array) {for-body}

◎·注意:var会遍历array的每个索引

◎·示例:

awk 'BEGIN{week["mon"]="monday";week["tue"]="tueday";week["ser"]="serday";for(i in week){print i ,week[i]}}'

[root@Centos7 ~]# awk 'BEGIN{week["mon"]="monday";week["tue"]="tueday";week["ser"]="serday";for(i in week){print i ,week[i]}}'
# 开始给变量给数组week 赋值 week["mon"]="monday";week["tue"]="tueday";week["ser"]="serday
# for( i  in  week)  变量i在数组 week中遍历,取得week的索引号,
# {print i ,week[i]} 打印显示 变量i的值和 week[i] 的值
tue tueday
ser serday
mon monday
[root@Centos7 ~]#

 

netstat  -tan  | awk  '/^tcp/{ state[$NF]++ }END{for ( i in state ){ print i ,state[i] }}'

[root@Centos7 ~]# netstat  -tan  | awk  '/^tcp/{ state[$NF]++ }END{for ( i in state ){ print i ,state[i] }}'
LISTEN 12
ESTABLISHED 3
#查看正常情况下的  netstat  -tan 的情况
#  /^tcp/ : 匹配以tcp开头的行,
#  { state[$NF]++ }  : 统计最后一个字段的数量分组及其数量统计
#  for ( i in state ){ print i ,state[i]}  :
[root@Centos7 ~]# netstat -tan
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:6011          0.0.0.0:*               LISTEN     
tcp        0     52 10.1.16.70:22           10.1.16.1:60325         ESTABLISHED
tcp        0      0 10.1.16.70:22           10.1.16.1:59953         ESTABLISHED
tcp        0      0 10.1.16.70:22           10.1.16.1:56490         ESTABLISHED
tcp6       0      0 :::80                   :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 ::1:631                 :::*                    LISTEN     
tcp6       0      0 ::1:25                  :::*                    LISTEN     
tcp6       0      0 ::1:6010                :::*                    LISTEN     
tcp6       0      0 ::1:6011                :::*                    LISTEN     
tcp6       0      0 10.1.16.70:80           10.1.16.1:60795         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60873         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60889         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60794         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60785         TIME_WAIT  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60845         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60887         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60847         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60888         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60872         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60848         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60886         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60793         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60796         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60849         FIN_WAIT2  
tcp6       0      0 10.1.16.70:80           10.1.16.1:60869         FIN_WAIT2

 

awk  '{ip[$1]++}END{for(iin ip) {print i,ip[i]}}'   /var/log/httpd/access_log

[root@Centos7 ~]# awk '/^[[:digit:]]/{logs[$1]++}END{for( i in logs ){printf"Access IP: %-10s Count:  %-3d\n",i,logs[i]}}' /var/log/httpd/access_log 
# 统计访问网站IP地址统计
#  /^[[:digit:]]/{logs[$1]++} : 匹配以数字开头,申明变量保存第一段的是IP地址数量统计。
#  for( i in logs ) :让 i 取得logs数组中 索引号(索引号即为IP)
#  按格式打印 IP地址 与 访问次数的统计
Access IP: 10.1.44.44 Count:  9  
Access IP: 10.1.16.61 Count:  9  
Access IP: 10.1.16.1  Count:  49 
[root@Centos7 ~]#

§·awk内建函数

数值处理:

rand():返回01之间一个随机数

awk'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'

字符串处理:

length([s]):返回指定字符串的长度

sub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并将第一个匹配的内容替换为s

echo "2008:08:08 08:08:08" | awk'sub(/:/,-",$1)'

gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容

echo "2008:08:08 08:08:08" | awkgsub(/:/,"",$1)'

split(s,array,[r]):以r为分隔符,切割字符s,并将切割后的结果保存至array所表示的数组中,

第一个索引值为1,第二个索引值为2,

 

awk  'BEGIN{srand();for(i=1;i<=10;i++){printf"Rand :%-1.8f Rand init:%-10d\n", rand() ,int(rand()*100)}}'

[root@Centos7 dev]# awk 'BEGIN{srand();for(i=1;i<=10;i++){printf"Rand :%-1.8f Rand init:%-10d\n", rand() ,int(rand()*100)}}'
# srand() 是一个函数,rand()只用通过srand()函数的出现才可以正常的工作,生成0-1之间的随机数
#生成10个随机数
Rand :0.18251386 Rand init:11        
Rand :0.19172835 Rand init:38        
Rand :0.25055455 Rand init:64        
Rand :0.48638138 Rand init:55        
Rand :0.21168378 Rand init:63        
Rand :0.17734465 Rand init:9         
Rand :0.36041239 Rand init:83        
Rand :0.57846720 Rand init:30        
Rand :0.17588418 Rand init:28        
Rand :0.01415744 Rand init:34        
[root@Centos7 dev]#

netstat  -tan | awk  '/^tcp/{split($5,ip,":");count[ip[1]]++;print $5}END{{print "========="}for( i in count ){ print i, count[i]}}'

[root@]# netstat  -tan | awk  '/^tcp/{split($5,ip,":");count[ip[1]]++;print $5}END{{print "========="}for( i in count ){ print i, count[i]}}'
#  {split($5,ip,":")  :把netstat  -tan 的第五段取出来,并以 : 为分隔符,把每段保存在数组 ip中,
# 处理第1行时 :  ip[1]= 0.0.0.0  ip[2]= *
  处理第1行时 : count[0.0.0.0]=1
#处理第2行时: ip[1]= 0.0.0.0  ip[2]= *
 处理第2行时:count[0.0.0.0]=2
#处理第7行时:ip[1]= 10.1.16.1  ip[2]= 60325
 处理第7行时: count[10.1.16.1]=1
#处理第8行时:ip[1]=(空)    ip[2]=(空)  ip[3]=(空)    ip[2]=* (由于第8行分号较多,分隔成的索引号有4个)
 处理第8行时:count[(空)]=1
0.0.0.0:*
0.0.0.0:*
0.0.0.0:*
0.0.0.0:*
0.0.0.0:*
10.1.16.1:60325
:::*
:::*
:::*
:::*
:::*
=========
 5
0.0.0.0 5
10.1.16.1 1
[root@Centos7 dev]#

§·awk自建函数

自定义函数

格式:

function name ( parameter, parameter, ... ) {
      statements
      return expression
}

示例:

#cat fun.awk
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}

#awk  –f  fun.awk

§·调用系统命令

※·awk中调用shell命令

system命令

空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律用""引用起来。

awk BEGIN'{system("hostname") }'

awk'BEGIN{score=100; system("echo your score is " score) }'

 

※·awk脚本

awk程序写成脚本,直接调用或执行

示例:

#cat f1.awk

if($3>=1000)print $1,$3}

#awk -F: -f f1.awk /etc/passwd

#cat f2.awk

#!/bin/awk f

#this is a awk script

{if($3>=1000)print $1,$3}

#chmod +x f2.awk

#f2.awk F: /etc/passwd

※·向awk脚本传递参数

格式:

 awkfile  var=value  var2=value2… Inputfile

示例:

#cat test.awk
#!/bin/awk –f
{if($3 >=min && $3<=max)print $1,$3}

#chmod  +x  test.awk

#test.awk   -F: min=100 max=200  /etc/passwd

 

§·练习

1、两个文件的内容如下,使用awk以后,写出输出后的文件内容

file1

1:beijing:1322676:::

2:shanghai:222676:::

3:guangdong:342676:::

file2

1:x:d3dn1

2:y:DWHh0

3:z:hWX9Y

awk 'BEGIN{OFS=FS=":"}NR==FNR{a[$1]=$2;}NR>FNR{$2=a[$1];print} file1 file2

 

[root@localhost ~]# awk 'BEGIN{OFS=FS=":"}NR==FNR{a[$1]=$2;}NR>FNR{$2=a[$1];print}' file1 file2
#分析 BEGIN{OFS=FS=":"} 定义文件分隔符为 : ,定义输出字段分隔符为 :
#NR==FNR{a[$1]=$2;} 当NR==FNR时,数组 a[$1]=$2,即使file1文件中,a[1]=beijing,a[2]=shanghai,a[3]=guangdong
#NR>FNR{$2=a[$1] 当NR>FNR时,即是在file2中,$2=a[$1],即是:x=beijing ,y=shanghai,z=guangdong
1:beijing:d3dn1
2:shanghai:DWHh0
3:guangdong:hWX9Y
[root@localhost ~]#

  

2、统计/etc/fstab文件中每个文件系统类型出现的次数

 awk  '/^[^#]/{a[$3]++}END{for( i in a ){printf"filesystem is :%-7s count : %-5d\n",i,a[i]}}' fstab.bak

[root@localhost ~]# awk  '/^[^#]/{a[$3]++}END{for( i in a ){printf"filesystem is :%-7s count : %-5d\n",i,a[i]}}' fstab.bak 
filesystem is :swap    count : 5    
filesystem is :ext4    count : 5    
filesystem is :xfs     count : 5

 

3、统计/etc/fstab文件中每个单词出现的次数;

awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' fstab.bak

[root@localhost ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' fstab.bak 
man 1
and/or 1
maintained 1
UUID=d0e00dc6-365b-48e7-8ec4-1c06970d2b89 5
xfs 5
/dev/mapper/centos-root 5
UUID=60a26f51-d413-4acc-94ff-5573f8ad3a59 5
14 1
Accessible 1
# 7
Thu 1
are 1
defaults 15
blkid(8) 1
/ 5
0 20
See 1
1 5
2 5
Created 1
on 1
mount(8) 1
ext4 5
anaconda 1
fstab(5), 1
/boot 5
00:13:05 1
findfs(8), 1
2016 1
'/dev/disk' 1
by 2
/etc/fstab 1
pages 1
more 1
info 1
swap 10
Jul 1
filesystems, 1
reference, 1
for 1
under 1
[root@localhost ~]#

原创文章,作者:linux_root,如若转载,请注明出处:http://www.178linux.com/47932

评论列表(1条)

  • 马哥教育
    马哥教育 2016-09-23 12:40

    awk是一个很方便的文本格式化工具,这也是以后面试题必会遇到的面试题,希望下来多加练习,熟练掌握,