shell mysql awk_【Shell】Shell编程之awk命令

awk是一种强大的数据处理工具,常用于处理文本和数据。它以行为单位读取文件,根据模式匹配执行指定动作。本文详细介绍了awk的格式、工作原理及多种使用示例,包括打印特定行、字段操作、条件匹配、格式化输出等,帮助读者深入掌握awk的使用。
摘要由CSDN通过智能技术生成

awk简介

awk是一种用于处理数据和生成报告的UNIX编程语言。处理的数据可以来自标准输入、一个会多个文件,也可以来自某个进程的输出。awk以逐行方式扫描文件(或输入),从第一行到最后一行,以查找匹配某个特定模式的文本行,并对这些文本执行(括在花括号中的)指定动作,如果只给出模式而未指定动作,则所有匹配该模式的行都显示在屏幕上;如果只指定动作而未定义模式,会对所有输入行执行指定动作。

awk格式

awk程序由awk命令、括在引号(或写在文件)中的程序指令以及输入文件的文件名几部分组成,若未指定输入文件,则输入来自标准输入,即键盘。

awk指令由模式、操作或者模式与操作组合组成,模式是由某种类型的表达式组成的语句,模式不能被括在大括号中,模式由括在两个正斜杠之间的正则表达式、一个或多个awk操作符组成的表达式组成;操作由括在大括号内的一条或多条语句组成,语句之间用分号隔开。

格式一

[root@db1 ~]# awk 'pattern' filename

[root@db1 ~]# awk '{action}' filename

[root@db1 ~]# awk 'pattern {action}' filename

示例1:打印包含Felix的行

[root@db1 shell_stu]# cat emp.txt

0001 Alen M 24

0002 Tiboo M 32

0003 Felix M 26

0004 Jack F 24

0005 Tim M 25

0006 Audi F 30

0007 Bobo F 32

0008 Geo M 21

0009 Andy F 19

00010 Peter M 28

[root@db1 shell_stu]# awk '/Felix/' emp.txt

0003 Felix M 26

[root@db1 shell_stu]#

示例2:打印第2列

[root@db1 shell_stu]# awk '{print $2}' emp.txt

Alen

Tiboo

Felix

Jack

Tim

Audi

Bobo

Geo

Andy

Peter

示例3:打印包含Alen行的第2和4字段

[root@db1 shell_stu]# awk '/Alen/{print $2,$4}' emp.txt

Alen 24

格式二

[root@db1 ~]# command | awk 'pattern'

[root@db1 ~]# command | awk '{action}'

[root@db1 ~]# command | awk 'pattern {action}'

示例1:打印磁盘可用空间大于等于2561100的行

[root@db1 ~]# df | awk '$4 >= 2561100'

Filesystem 1K-blocks Used Available Use% Mounted on

/dev/sda1 14317576 6664348 6902892 50% /

/dev/sda2 3997376 1210180 2561100 33% /u01

示例2:打印/etc/passwd文件中mysql行的第6列

[root@db1 ~]# cat /etc/passwd |awk -F : '/mysql/{print $6}'---F表示字段分隔符

/home/mysql

awk工作原理

测试数据为:

[root@db1 shell_stu]# cat emp.txt

0001 Alen M 24

0002 Tiboo M 32

0003 Felix M 26

0004 Jack F 24

0005 Tim M 25

0006 Audi F 30

0007 Bobo F 32

0008 Geo M 21

0009 Andy F 19

00010 Peter M 28

执行命令为:

[root@db1 shell_stu]# awk '{print $2,$4}' emp.txt

Alen 24

Tiboo 32

Felix 26

Jack 24

Tim 25

Audi 30

Bobo 32

Geo 21

Andy 19

Peter 28

1)awk使用一行作为输入,并将该行赋给内部变量$0,默认时每一行也称为一个记录,以换行符结束;

4247227efd0347a31ac1104a0f7944f0.png

2)然后,行被分解成字段,每个字段存储在已编号的变量中,从$1开始;

1660563e259df8591c76a70c5a4ed285.png

3)awk通过内部变量FS来确定字段的分隔符,初始值FS为空格--包含制表符和空格符,如果需要使用其他字段分隔符,则需将FS设为新的字段分隔符;

4)awk打印字段时,将以{print $2,$4}方式使用print函数;

5)awk输出之后,将从文件中获取另一行,并将其存储到$0中,覆盖原来的内容,然后将新的字符串分割为字段并进行处理,直到整个文件所有行处理完毕。

格式化输出

print函数

awk命令的操作部分放在大括号内,若未指定操作,则匹配模式时,awk会采取默认形式,即在屏幕上打印。可以使用{print}形式显式调用print函数,print函数的参数可以是变量、数值或字符串常量。字符串必须用双引号括起来,参数之间用逗号分隔。

[root@db1 shell_stu]# date | awk '{print "Today is " $1 ,", Month is " $2, ", Year is "$6}'

Today is Mon , Month is Mar , Year is 2018

--使用转义\n表示换行

[root@db1 shell_stu]# date | awk '{print "Today is " $1 ,"\nMonth is " $2, "\nYear is "$6}'

Today is Mon

Month is Mar

Year is 2018

--利用制表符\t打印输出

[root@db1 shell_stu]# awk '/Alen/{print "\t\tHave a nice day ,"$2" !"}' emp.txt

Have a nice day ,Alen !

printf函数

--%表示让printf做好准备,-表示左对齐,s表示字符串

[root@db1 shell_stu]# awk '/Alen/,/Felix/{printf "The ID is %-5s , Name is %-10s\n",$1,$2 }' emp.txt

The ID is 0001 , Name is Alen

The ID is 0002 , Name is Tiboo

The ID is 0003 , Name is Felix

文件中awk命令

若awk命令写在文件里,需用-f指定awk的文件名,后再加上所要处理的输入文件的文件名。

示例:若匹配到Felix,则打印Hello Felix,其他的打印第1,2,3列

[root@db1 shell_stu]# cat script.txt

/Felix/{print "Hello "$2}

{print $1,$2,$3}

[root@db1 shell_stu]# awk -f script.txt emp.txt

0001 Alen M

0002 Tiboo M

Hello Felix

0003 Felix M

0004 Jack F

0005 Tim M

0006 Audi F

0007 Bobo F

0008 Geo M

0009 Andy F

00010 Peter M

awk命令示例

测试数据

[root@db1 shell_stu]# cat emp.txt

0001 AleN M 24

0002 Tiboo M 32

0003 Felix M 26

0004 JacK F 24

0005 Tim M 25

0006 Audi F 30

0007 Bobo F 32

0008 Geo M 21

0009 Andy F 19

00010 Peter M 28

00011 Allen M 26

1、匹配整行

--显示以0001开始的行

[root@db1 shell_stu]# awk '/^0001/' emp.txt

0001 Alen M 24

00010 Peter M 28

00011 Allen M 26

--显示第二列中以大写字母开始,后跟一个或多个小写字母,最后一个字母为大写的行

[root@db1 shell_stu]# awk '$2~/^[A-Z][a-z]+[A-Z]/' emp.txt

0001 AleN M 24

0004 JacK F 24

2、匹配操作符~

--~用于匹配第2列以Al开头的行

[root@db1 shell_stu]# awk '$2~/^Al/' emp.txt

0001 AleN M 24

00011 Allen M 26

--匹配第2列以o结尾的行

[root@db1 shell_stu]# awk '$2~/o$/' emp.txt

0002 Tiboo M 32

0007 Bobo F 32

0008 Geo M 21

--匹配第2列不以o结尾的行

[root@db1 shell_stu]# awk '$2!~/o$/' emp.txt

0001 AleN M 24

0003 Felix M 26

0004 JacK F 24

0005 Tim M 25

0006 Audi F 30

0009 Andy F 19

00010 Peter M 28

00011 Allen M 26

3、打印第2,3列

[root@db1 shell_stu]# awk '{print $2,$3}' emp.txt

AleN M

Tiboo M

Felix M

JacK F

Tim M

Audi F

Bobo F

Geo M

Andy F

Peter M

Allen M

4、打印所有记录

[root@db1 shell_stu]# awk '{print $0}' emp.txt

0001 AleN M 24

0002 Tiboo M 32

0003 Felix M 26

0004 JacK F 24

0005 Tim M 25

0006 Audi F 30

0007 Bobo F 32

0008 Geo M 21

0009 Andy F 19

00010 Peter M 28

00011 Allen M 26

5、使用NF来保存记录的字段数

[root@db1 shell_stu]# awk '{print $0,"Number of fields is "NF}' emp.txt

0001 AleN M 24 Number of fields is 4

0002 Tiboo M 32 Number of fields is 4

0003 Felix M 26 Number of fields is 4

0004 JacK F 24 Number of fields is 4

0005 Tim M 25 Number of fields is 4

0006 Audi F 30 Number of fields is 4

0007 Bobo F 32 Number of fields is 4

0008 Geo M 21 Number of fields is 4

0009 Andy F 19 Number of fields is 4

00010 Peter M 28 Number of fields is 4

00011 Allen M 26 Number of fields is 4

6、模式与操作组合

--打印0001开头的第2、3列

[root@db1 shell_stu]# awk '/^0001/{print $2,$3}' emp.txt

AleN M

Peter M

Allen M

--第2列以T或F开头,打印第1、2、4列

[root@db1 shell_stu]# awk '$2~/^[TF]/{print $1,$2,$4}' emp.txt

0002 Tiboo 32

0003 Felix 26

0005 Tim 25

--若第4个字段大于25,则打印1、2、4列

[root@db1 shell_stu]# awk '$4>25{print $1,$2,$4}' emp.txt

0002 Tiboo 32

0003 Felix 26

0006 Audi 30

0007 Bobo 32

00010 Peter 28

00011 Allen 26

--如果第2列以oo结尾,则打印Hello,Tiboo

[root@db1 shell_stu]# awk '$2~/oo$/{print "Hello ,"$2}' emp.txt

Hello ,Tiboo

7、字段分隔符-F

--默认字段分隔符是空格,NF表示字段数

[root@db1 shell_stu]# cat /etc/passwd |grep tss| awk '{print NF}'

11

--指定字段分隔符为:

[root@db1 shell_stu]# cat /etc/passwd |grep tss| awk -F: '{print NF}'

--打印长度为3的行

[root@db1 shell_stu]# awk '$2~/^.{3}$/' emp.txt

0005 Tim M 25

0008 Geo M 21

8、范围匹配

[root@db1 shell_stu]# awk '/Felix/,/Audi/' emp.txt

0003 Felix M 26

0004 JacK F 24

0005 Tim M 25

0006 Audi F 30

--或者用NR指示行数

[root@strong shell_stu]# awk 'NR==3,NR==6' emp.txt

0003 Felix M 26

0004 JacK F 24

0005 Tim M 25

0006 Audi F 30

9、表达式运算

--第2列等于Audi并且4列大于25时打印该行,逻辑与操作

[root@db1 shell_stu]# awk '$2=="Audi"&&$4>25' emp.txt

0006 Audi F 30

--打印第4列小于等于25的行,逻辑非操作

[root@db1 shell_stu]# awk '!($4>25)' emp.txt

0001 AleN M 24

0004 JacK F 24

0005 Tim M 25

0008 Geo M 21

0009 Andy F 19

10、算术运算

[root@db1 shell_stu]# awk '/Felix/{print $2,$4+5}' emp.txt

Felix 31

11、条件运算符

[root@db1 shell_stu]# awk 'NR>=2&&NR<=4{print ($4>30?"High "$4:"Low "$4)}' emp.txt

High 32

Low 26

Low 24

12、赋值运算符

[root@db1 shell_stu]# awk 'NR==1{$2="Alen";print $2}' emp.txt

Alen

[root@db1 shell_stu]# awk 'NR==1{$2="Alen";print}' emp.txt

0001 Alen M 24

13、自定义变量

[root@db1 shell_stu]# awk '/Tim/{age=$4+5;print $0,age }' emp.txt

0005 Tim M 25 30

[root@db1 shell_stu]# awk '/Tim/{$5=$4+10;print}' emp.txt

0005 Tim M 25 35

14、内置变量

--NR表示行号,$NF表示最后一个字段

[root@strong shell_stu]# awk '$2=="Tim"{print NR,$1,$2,$NF}' emp.txt

5 0005 Tim 25

--忽略大小写{IGNORECASE=1}

[root@strong shell_stu]# awk '{IGNORECASE=1};$2=="alen"{print $0}' emp.txt

0001 AleN M 24

--RS表示换行符,print默认一个换行符,又加一个

[root@strong shell_stu]# awk 'NR==1,NR==3{print NR,$1,$2,$NF,RS}' emp.txt

1 0001 AleN 24

2 0002 Tiboo 32

3 0003 Felix 26

15、BEGIN和END模式

[root@strong shell_stu]# awk 'BEGIN{print "This is executed firstly "}/Tim/{print}' emp.txt

This is executed firstly

0005 Tim M 25

[root@strong shell_stu]# awk 'BEGIN{print "\t\t------------------------Employees-------------------\n"}\

NR==2,NR==4{print $0}' emp.txt

------------------------Employees-------------------

0002 Tiboo M 32

0003 Felix M 26

0004 JacK F 24

[root@strong shell_stu]# awk 'END{print "Number of fields is "NR}/Tiboo/,/Bobo/{print}' emp.txt

0002 Tiboo M 32

0003 Felix M 26

0004 JacK F 24

0005 Tim M 25

0006 Audi F 30

0007 Bobo F 32

Number of fields is 11

16、输出重定向

--文件名必须用双引号括起来

[root@strong shell_stu]# awk '/Tim/,/Bobo/{print $1,$2 > "res.txt"}' emp.txt

[root@strong shell_stu]# ll

total 8

-rw-r--r--. 1 root root 209 Mar 26 18:33 emp.txt

-rw-r--r--. 1 root root 29 Mar 26 19:10 res.txt

[root@strong shell_stu]# cat res.txt

0005 Tim

0006 Audi

0007 Bobo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值