且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

awk最简单明了入门方法

更新时间:2022-09-26 20:35:04

Awk,sed,grep三剑客

Grep合适单纯的查找或者匹配文本

Sed合适编辑匹配到的文本

Awk更合适格式化,对文本进行比较复杂的处理

 

Awk语法 awk [options] program file1,file2........

 

# awk ‘条件1{动作1} 条件2{动作2}…’ 文件名

条件(Pattern):

一般使用关系表达式作为条件

x > 10 判断变量 x是否大于10

x>=10 大于等于

x<=10 小于等于

动作(Action):

格式化输出

流程控制语句

 

Awk基本了解篇

1先从简单的一个打印动作来初步了解awk

创建测试数据

[root@localhost tmp]# echo test >testd

[root@localhost tmp]# cat testd

test

[root@localhost tmp]# awk '{print}' testd

Test

 

场景2

[root@localhost tmp]# df

Filesystem     1K-blocks    Used Available Use% Mounted on

/dev/sda3       18375548 3566396  13875728  21% /

tmpfs             502204       0    502204   0% /dev/shm

/dev/sda1         198337   29662    158435  16% /boot

打印第五列

[root@localhost tmp]# df |awk '{print $5}'                 

Use%

21%

0%

16%

 

一次打印多列,打印第一列和第五列

[root@localhost tmp]# df |awk '{print $1,$5}'

Filesystem Use%

/dev/sda3 21%

tmpfs 0%

/dev/sda1 16%

 

[root@localhost tmp]# df |grep "sda3" |awk '{print $1,$5}'

/dev/sda3 21%

 

 

除了输出文本中的列,还可以加入自己的字段,将自己的字段和文件中的列结合起来,如

[root@localhost tmp]# cat >>testd <<eof

> lixunhuan

> afei

> shangguangjinghong

> wangliqin

> eof

[root@localhost tmp]# awk '{print $1,"welcome"}' testd

test welcome

lixunhuan welcome

afei welcome

shangguangjinghong welcome

wangliqin welcome

 

 

[root@localhost tmp]# cat testd

test    98

lixunhuan       100

afei    95

shangguangjinghong      86

wangliqin       100

[root@localhost tmp]# awk '{print "name:" $1,"socer:" $2}' testd

name:test socer:98

name:lixunhuan socer:100

name:afei socer:95

name:shangguangjinghong socer:86

name:wangliqin socer:100

 

 

输出整行两种方法,一是$0  ,而是什么都不加

 

[root@localhost tmp]# cat testd

test    98

lixunhuan       100

afei    95

shangguangjinghong      86

wangliqin       100

[root@localhost tmp]# awk '{print}' testd

test    98

lixunhuan       100

afei    95

shangguangjinghong      86

wangliqin       100

[root@localhost tmp]# awk '{print $0}' testd

test    98

lixunhuan       100

afei    95

shangguangjinghong      86

wangliqin       100

 

 

Awk是逐行处理的,刚才已经演示了最常用的动作print

介绍一下特殊模式beginend

Begin模式指定了处理文本之前所需要执行的操作

End模式指定了处理完所有行之后所需要执行的操作

 

[root@localhost tmp]# cat testd

test    98

lixunhuan       100

afei    95

shangguangjinghong      86

wangliqin       100

[root@localhost tmp]# awk 'BEGIN {print "aa","bb"}' testd

aa bb

[root@localhost tmp]# awk 'BEGIN {print "aa","bb"}'

aa bb

 

经过试验发现,我们不需要输入任何文件来源,awk就直接输出信息了,因为begin模式表示,在处理指定文本之前,需要先执行begin模式中的指定操作,而上述试验我只是让他做出打印输出,这时候如果我们想要先执行begin之前的作用之外,再执行我们我们自定义执行的动作去操作文本,例如

 

[root@localhost tmp]# cat testd

test    98

lixunhuan       100

afei    95

shangguangjinghong      86

wangliqin       100

[root@localhost tmp]# awk 'BEGIN{print "aa","bb"} {print $1,$2}' testd

aa bb

test 98

lixunhuan 100

afei 95

shangguangjinghong 86

wangliqin 100

 

End模式就是在处理完所有指定的文本后,需要执行的作用,通常我们可以结合beginend模式一起使用

 

[root@localhost tmp]# awk 'BEGIN{print "aa","bb"}{print $1,$2} END {print "cc","dd"}' testd  

awk最简单明了入门方法aa bb

test 98

lixunhuan 100

afei 95

shangguangjinghong 86

wangliqin 100

cc dd

 

返回结果中有没有那种表头,表内容,表尾的那种感觉,这就是awk对文本格式化的能力

 

 

Awk分隔符  

 

Awk默认分隔符是空格,但是这样描述并不十分准确,awk的分隔符分为两种,输出分隔符和输入分隔符

 

输入分隔符:默认是空白字符(空格),默认是以空格为分隔符对每一行进行分隔,我们可以指定我们想要的分隔符来分隔  参数-F

 

[root@localhost tmp]# cat >>test <<eof

> abc##luliechu##iuy#dd

> 8u#liusheng#li#32

> eof

[root@localhost tmp]# cat test

abc##luliechu##iuy#dd

8u#liusheng#li#32

[root@localhost tmp]# awk -F# '{print $1,$2,$3}' test

abc  luliechu

8u liusheng li

还可以设置内置变量FS来指定分隔符,需要使用-V选项 ,如 -v FS=#

[root@localhost tmp]# cat test

abc##luliechu##iuy#dd

8u#liusheng#li#32

[root@localhost tmp]# awk -F# '{print $1,$2,$3}' test

abc  luliechu

8u liusheng li

[root@localhost tmp]# ^C

[root@localhost tmp]# awk -v FS='#' '{print $1,$2,$3}' test

abc  luliechu

8u liusheng li

 

可以看出效果是一样的

 

输出分隔符:当我们要对处理完的文本进行输出的时候,以什么文本或符号作为分隔符

默认是空白字符(空格),我们可以用内置变量OFS来设定awk的输出分隔符,使用变量的时候都需要配合使用-v选项

 

 

 [root@localhost tmp]# ls

public  test  test1.txt  test2.txt  test3.txt  test4.txt  test5.txt  testd

[root@localhost tmp]# rm -f test test{1..5}.txt

[root@localhost tmp]# ls

public  testd

[root@localhost tmp]# cat >>test <<eof

> luliechu 123

> lixunhuan 145

> afei 98

> eof

[root@localhost tmp]# awk -v OFS="+" '{print $1,$2}' test

luliechu+123

lixunhuan+145

afei+98

 

同时指定输入分隔符合输出分隔符

[root@localhost tmp]# cat >>test <<eof

> luliechu#123

> lixuhuan#150

> eof

[root@localhost tmp]# awk -v FS="#" -v OFS='成绩=' '{print $1,$2}' test

luliechu成绩=123

lixuhuan成绩=150

 

在输出的时候合并一起显示,将两列合并显示

 

 

[root@localhost tmp]# awk '{print $1$2}' test

luliechu#123

lixuhuan#150

 

Awk变量

Awk变量分为自定义变量和内置变量

常见自定义变量以及作用如下

FS 输出分隔符

OFS 输入分隔符

ORS 输出换行符

NF 当前行的字段的个数(当前行被分隔成了多少列)

NR 行号

FNR 各文件分别计数的行号

FILENAME 当前文件名

ARGC 命令行参数的个数

ARGV 数组

 

NR实例

[root@localhost tmp]# cat test

luliechu 123

lixunhuan 145

afei 98

luliechu#123

lixuhuan#150

[root@localhost tmp]# awk '{print NR}' test

1

2

3

4

5

 

NF实例   显示每一行的行号以及每一行对应有多少列

[root@localhost tmp]# cat test

luliechu 123

lixunhuan 145

afei 98

luliechu#123

lixuhuan#150

[root@localhost tmp]# awk '{print NR}' test

1

2

3

4

5

[root@localhost tmp]# awk '{print NR,NF}' test

1 2

2 2

3 2

4 1

5 1

 

添加行号输出

[root@localhost tmp]# awk '{print NR,$0}' test

1 luliechu 123

2 lixunhuan 145

3 afei 98

4 luliechu#123

5 lixuhuan#150

 

如果我们同时处理多个文件时候行号显示

[root@localhost tmp]# awk '{print NR,$0}' test test1

1 luliechu 123

2 lixunhuan 145

3 afei 98

4 luliechu#123

5 lixuhuan#150

昔在九江上

遥望九华峰

天河挂绿水

秀出九芙蓉

10 我欲一挥手

11 谁人可想从

从返回结果可以看出,如果使用NR显示行号,那么多个文件的所有行会按照顺序进行排序,如果我们要分别显示两个文件的行号,就需要用到内置变量FNR

[root@localhost tmp]# awk '{print FNR,$0}' test test1

1 luliechu 123

2 lixunhuan 145

3 afei 98

4 luliechu#123

5 lixuhuan#150

昔在九江上

遥望九华峰

天河挂绿水

秀出九芙蓉

我欲一挥手

谁人可想从

 

输入行分隔符RS,默认是回车换行

假入我想让他认为每次遇到一个#就换行

[root@localhost tmp]# cat test

luliechu 123

lixunhuan 145

afei 98

luliechu#123

lixuhuan#150

[root@localhost tmp]# sed -n 1,3d test

[root@localhost tmp]# sed -i 1,3d test  

[root@localhost tmp]# cat test

luliechu#123

lixuhuan#150

[root@localhost tmp]# awk -v RS="#" '{print NR,$0}' test

1 luliechu

2 123

lixuhuan

3 150

 

输出行分隔符,也就是在它为我们换行后会加上我们需要的标识,默认是回车,是没有任何标识的

[root@localhost tmp]# cat test

luliechu#123

lixuhuan#150

[root@localhost tmp]# awk -v ORS="+" '{print NR,$0}' test

1 luliechu#123+2 lixuhuan#150+[root@localhost tmp]#

 

输入换行符和输出换行符同时演示  RS ORS

[root@localhost tmp]# awk -v RS="#" -v ORS="+" '{print NR,$0}' test

1 luliechu+2 123

lixuhuan+3 150

+[root@localhost tmp]# cat test

luliechu#123

lixuhuan#150

 

自定义变量案例

[root@localhost tmp]# awk 'BEGIN {myname="luliechu" ; print myname}'  

Luliechu

本文转自    探花无情   51CTO博客,原文链接:http://blog.51cto.com/983865387/1917713