linux基础学习之AWK

内容:

1、awk输出(print、printf)

2、awk变量(内建变量和定义变量)

3、awk数组

4、awk重定向输出

5、awk操作符

6、awk常见模式类型

7、awk控制及循环语句

8、awk内置函数

awk:(其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母)

awk是一款强大的报告生成器,不同于sed和grep,它的侧重点是如何把文本信息更好的展示出来,常用与统计和格式化输出。

awk相当于微型的shell,有着自己一套语法结构,例如:循环结构,数组,条件判断,函数,内置变量等功能。处理对象一般纯文本文件或纯文本信息。

在linux中用的GUN是gawk,和awk其实是同一个命令:

[19:48 root@Centos6.8~]# ll /bin/awk 
lrwxrwxrwx. 1 root root 4 Jul 20 02:11 /bin/awk -> gawk

语法:

awk [options] 'script' file1 file2, …

awk [options] 'PATTERN { action }' file1 file2, …:两条语法等价,上面的脚本可分为两部分,模式和动作,注意action要用{}引起来

-F:指定分割符

处理过程:
逐行读取,然后按照一定的分割符(默认空格)把该行内容进行内容分片,称为字段,每一个字段内容用$1,$2..表示,$0表示该整行,此外在awk中打印变量不需要$引用
Awk的工作方式:
1)Awk 一次读取文件中的一行
2)对于一行,按照给定的pattern的顺序进行匹配,如果匹配则执行对应的 Action
3)如果没有匹配上则不执行任何动作
4)在上诉的语法中,Pattern 和 Action 是可选的,但是必须提供其中一个
5)如果Pattern未提供,则对所有的输入行执行 Action 操作
6)如果 Action 未提供,则默认打印出该行的数据
7){} 这种 Action 不做任何事情,和未提供的 Action 的工作方式不一样
8)Action 中的语句应该使用分号分隔

工作步骤:

第一步:执行BEGIN{action;… }语句块中的语句【在读取文件前就开始打印,所以后面可以不加文件作为参数】

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

第三步:当读至输入流末尾时,执行END{action;…}语句块【后面也要加上文件作为参数】

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

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

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

一、常用输出说明:

1、print:

print item1, item2,…

.各项目之间使用逗号分隔,而输出时则使用输出分隔符分隔

.输出的各item可以字符串或数值、当前记录的字段、变量或awk的表达式,数值会被隐式转换为字符串后输出

.与bash的位置变量相似 print后面item如果省略,相当于print $0,若输出空白,使用pirnt ""

演示说明:

[19:17 root@Centos6.8~]# awk -F: '{print $1,$3}' /etc/passwd
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
[19:34 root@Centos6.8~]# awk -F: '{print $1,$3,$7}' /etc/passwd
root 0 /bin/bash
bin 1 /sbin/nologin
daemon 2 /sbin/nologin
adm 3 /sbin/nologin
lp 4 /sbin/nologin
sync 5 /bin/sync
shutdown 6 /sbin/shutdown
halt 7 /sbin/halt
mail 8 /sbin/nologin
uucp 10 /sbin/nologin
operator 11 /sbin/nologin
games 12 /sbin/nologin
gopher 13 /sbin/nologin

2、printf:带格式的输出

语法:printf format, item1, item2,…

说明:

.要指定format

.不会自动换行;如需换行则需要给出\n

.format用于为后面的每个item指定其输出格式

format格式的指示符都以%开头,后跟一个字符;如下:

%c: 显示字符的ASCII码;

%d, %i:十进制整数;

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

%f: 显示浮点数;

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

%s: 显示字符串;

%u: 无符号整数;

%%: 显示%自身;

修饰符:

N: 显示宽度;

-: 左对齐;

+:显示数值符号;

演示说明:

[19:35 root@Centos6.8~]# awk -F: '{printf "%s%d",$1,$3}' /etc/passwd
root0bin1daemon2adm3lp4sync5shutdown6halt7mail8uucp10operator11games12gopher13ftp14nobody99dbus81usbmuxd113rpc32rtkit499avahi-autoipd170vcsa69abrt173rpcuser29nfsnobody65534haldaemon68ntp38apache48saslauth498postfix89mysql27gdm42pulse497sshd74tcpdump72hill500nihao501[19:36 root@Centos6.8~]# awk -F: '{printf "%s%d\n",$1,$3}' /etc/passwd
[19:36 root@Centos6.8~]# awk -F: '{printf "%s%d\n",$1,$3}' /etc/passwd
root0
bin1
daemon2
adm3
lp4
sync5
shutdown6
halt7
mail8
uucp10
operator11
games12
gopher13
[19:36 root@Centos6.8~]# awk -F: '{printf "%-20s%-10s\n",$1,$3}' /etc/passwd
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

二、awk变量

1、awk内置变量之记录变量:

FS: field separator,读取文件本时,所使用字段分隔符;

RS: Record separator,输入文本信息所使用的换行符;

OFS: Output Filed Separator: 

ORS:Output Row Separator:

演示说明:

[19:42 root@Centos6.8~]# awk 'BEGIN{FS=":"}{print $1,$3}' /etc/passwd
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

[19:43 root@Centos6.8~]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$3}' /etc/passwd
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

2、awk内置变量之数据变量:

NR: The number of input records,awk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数;

NF:Number of Field,当前记录的field个数;

FNR: 与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数;

ARGV: 数组,保存命令行本身这个字符串,如awk '{print $0}' a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt;

ARGC: awk命令的参数的个数;

FILENAME: awk命令所处理的文件的名称;

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

演示说明:

[19:45 root@Centos6.8~]# awk -F: '{print NR,$1}' /etc/issue /etc/passwd #NR统计所有文件的总行数
1 CentOS release 6.8 (Final)
2 Kernel \r on an \m
3 $(hostname)
4 `date`
5 root
6 bin
7 daemon
8 adm
9 lp
10 sync
11 shutdown
12 halt
13 mail
14 uucp
15 operator
16 games
17 gopher

[19:48 root@Centos6.8~]# awk  '{print NF,$1}' /etc/issue #显示每一行的字段个数
4 CentOS
5 Kernel
1 $(hostname)
1 `date`

3、用户自定义变量

可以命令行中通过-v选项自定义变量

gawk允许用户自定义自己的变量以便在程序代码中使用,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头。gawk变量名称区分字符大小写。

演示说明:

[19:52 root@Centos6.8~]# awk -F: -v A="nihao" '{print A,$1}' /etc/passwd  #同时也证明了变量的引用不需要$引用
nihao root
nihao bin
nihao daemon
nihao adm
nihao lp
nihao sync
nihao shutdown
nihao halt
nihao mail
nihao uucp
nihao operator
nihao games
nihao gopher

三、awk数组

定义方法

1:可以用数值作数组索引(下标)

array[1]=“hello awk”

Tarray[2]=“9527”

2:可以用字符串作数组索引(下标)

array[“first”]=“hello ”

array[“last”]=”awk”

array[“birth”]=”9527”

使用中 print array[1] 将得到”hello awk” 而 print array[2] 和 print[“birth”] 都将得到 ”9527” 。

例子:

split(string, array [, fieldsep [, seps ] ])

功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中

[16:44 root@Centos6.8~]#awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}'
4 test
1 it
2 is
3 a

for…in 输出,因为数组是关联数组,默认是无序的。所以通过for…in 得到是无序的数组。如果需要得到有序数组,需要通过下标获得。

[16:49 root@Centos6.8~]# awk 'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}' 
1 it
2 is
3 a
4 test

过滤重复选项用法(利用真假判断):

[11:14 root@centos6.8~]# cat test 
1.1.1.1,1aaa
1.1.1.1,1bbb
1.1.1.1,1ccc
2.2.2.2,2aaa
2.2.2.2,2bbb
3.3.3.3,3aaa
[11:14 root@centos6.8~]# awk -F"," '!arry[$1]++' test 
1.1.1.1,1aaa
2.2.2.2,2aaa
3.3.3.3,3aaa

四、输出重定向

print items > output-file:保存到文件

print items >> output-file:追加到文件

print items | command:使用管道交给某些命令处理

演示说明:

[20:02 root@Centos6.8~]# awk -F: -v A="nihao" '{print A,$1 > "/root/awktest"}' /etc/passwd
[20:03 root@Centos6.8~]# cat awktest 
nihao root
nihao bin
nihao daemon
nihao adm
nihao lp
nihao sync
nihao shutdown
nihao halt
nihao mail
nihao uucp
nihao operator
nihao games
nihao gopher

五、awk操作符

1、算术操作符:

-x: 负值

+x: 转换为数值;

x^y: 

x**y: 次方

x*y: 乘法

x/y:除法

x+y:

x-y:

x%y:

2、赋值操作符:

=

+=

-=

*=

/=

%=

^=

**=

++

演示说明:

[21:41 root@Centos6.8~]# awk '{ x+=$2+$3 }{print $0,x}' test 
3 5 6 7 11
2 3 1 0 15
4 5 6 9 26
2 3 4 4 33
2 2 1 0 36
4 5 0 9 41
[21:41 root@Centos6.8~]# cat test 
3 5 6 7
2 3 1 0
4 5 6 9
2 3 4 4
2 2 1 0
4 5 0 9

需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,应以/[=]/替代;

3、比较操作符

x < y

x <= y

x > y

x >= y

x == y

x != y

x ~ y

x !~ y

4、逻辑关系符

&&

||

5、三目表示式

selector?if-true-exp:if-false-exp

6、函数调用:

function_name (para1,para2)

演示说明:

判断UID是否大于等于500,如果为真就显示“common user”,如果为假就显示“system user”

[20:10 root@Centos6.8~]# awk -F: '{$3<500?A="system user":A="common user"}{print $1,A}' /etc/passwd #三目操作表达式
root system user
bin system user
daemon system user
adm system user
lp system user
sync system user
shutdown system user
halt system user
mail system user
uucp system user
operator system user
games system user
gopher system user

六、常见的模式类型:

1、Regexp: 正则表达式,格式为/regular expression/

2、expresssion: 表达式,其值非0或为非空字符时满足条件,如:$1~/foo/【非精准匹配】或 $1 == "VALUE"【精准匹配】,用运算符~(匹配)和!~(不匹配)。

3、Ranges: 指定的匹配范围,格式为pat1,pat2

4、BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次(常用作标题和结尾说明)

5、Empty(空模式):匹配任意输入行;

演示说明:

[20:11 root@Centos6.8~]# awk -F: '/^r/{print $1,$3}' /etc/passwd #正则表达式使用
root 0
rpc 32
rtkit 499
rpcuser 29

[20:16 root@Centos6.8~]# awk -F: 'BEGIN{print "TEST BEGIN"}/^r/{print $1,$3}END{print "TEST OVER"}' /etc/passwd #BEGIN和END的使用演示
TEST BEGIN
root 0
rpc 32
rtkit 499
rpcuser 29
TEST OVER

七、控制语句

if-else

语法:if (condition) {then-body} else {[ else-body ]}

演示说明:

[10:10 root@centos6.8~]# df -P
Filesystem                   1024-blocks    Used Available Capacity Mounted on
/dev/mapper/VolGroup-lv_root    51475068 2740208  46113420       6% /
tmpfs                            1954768       0   1954768       0% /dev/shm
/dev/sda1                         487652   40654    421398       9% /boot
/dev/mapper/VolGroup-lv_home    10190136   36884   9628968       1% /home
[10:11 root@centos6.8~]# df -P|awk '{i=$5+0;if (i > 5){print $1,$5}}'
/dev/mapper/VolGroup-lv_root 6%
/dev/sda1 9%

注意:$N+0可以把$N强制去整数形式

[20:24 root@Centos6.8~]# awk -F: '{if ($3<500) {print $1,"systemm user"} else {print $1,"common user"}}' /etc/passwd
root systemm user
bin systemm user
daemon systemm user
adm systemm user
lp systemm user
sync systemm user
shutdown systemm user
halt systemm user
mail systemm user
uucp systemm user
operator systemm user
games systemm user
gopher systemm user

while

语法: while (condition){statement1; statment2; …}

[20:24 root@Centos6.8~]# awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd #每个的前三个字段逐行打印
root
x
0
bin
x
1
daemon
x
2
adm
x
3
lp
x
4
sync
x
5
shutdown
x
6
halt
x
7
mail
x
8
uucp
x
10
operator
x
11
games
x
12
gopher
x
13

for

语法: for ( variable assignment; condition; iteration process) { statement1, statement2, …}

演示说明:

[20:25 root@Centos6.8~]# awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd
root
x
0
bin
x
1
daemon
x
2
adm
x
3
lp
x
4
sync
x
5
shutdown
x
6
halt
x
7
mail
x
8
uucp
x
10
operator
x
11
games
x
12
gopher
x
13

for循环还可以用来遍历数组元素:

语法: for (i in array) {statement1, statement2, …}

case

语法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,… default: statement1, …}

break 和 continue

常用于循环或case语句中

next

提前结束对本行文本的处理,并接着处理下一行;例如,下面的命令将显示其ID号为奇数的用户:

演示说明:

[20:29 root@Centos6.8~]# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
bin 1
adm 3
sync 5
halt 7
operator 11
gopher 13

八、awk的内置函数

split(string, array [, fieldsep [, seps ] ])

功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中

length([string])

功能:返回string字符串中字符的个数;

[20:35 root@Centos6.8~]# awk -F: '{print $1,length($1)}' /etc/passwd
root 4
bin 3
daemon 6
adm 3
lp 2
sync 4
shutdown 8
halt 4
mail 4
uucp 4
operator 8
games 5
gopher 6

substr(string, start [, length])

功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;

system(command)

功能:执行系统command并将结果返回至awk命令

systime()

功能:取系统当前时间,默认显示秒

[20:30 root@Centos6.8~]#awk -F: '{print $1,systime()}' /etc/passwd
root 1472992355
bin 1472992355
daemon 1472992355
adm 1472992355
lp 1472992355
sync 1472992355
shutdown 1472992355
halt 1472992355
mail 1472992355
uucp 1472992355
operator 1472992355
games 1472992355
gopher 1472992355

tolower(s)

功能:将s中的所有字母转为小写

toupper(s)

功能:将s中的所有字母转为大写

[20:33 root@Centos6.8~]# awk -F: '{print $1,toupper($7)}' /etc/passwd
root /BIN/BASH
bin /SBIN/NOLOGIN
daemon /SBIN/NOLOGIN
adm /SBIN/NOLOGIN
lp /SBIN/NOLOGIN
sync /BIN/SYNC
shutdown /SBIN/SHUTDOWN
halt /SBIN/HALT
mail /SBIN/NOLOGIN
uucp /SBIN/NOLOGIN
operator /SBIN/NOLOGIN
games /SBIN/NOLOGIN
gopher /SBIN/NOLOGIN

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

评论列表(1条)

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

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