Linux三剑客之awk

1、awk 简介

awk其名称来自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

awk 是一种很棒的语言,它适合文本处理和报表生成,其语法较为常见,借鉴了某些语言的一些精华,如 C 语言等。在 linux 系统日常处理工作中,发挥很重要的作用,掌握了 awk将会使你的工作变的高大上。 awk 是三剑客的老大,利剑出鞘,必会不同凡响。

2、awk 语法

awk  '{pattern + action}'  {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

3、awk 原理

通过一个简短的命令,我们来了解其工作原理

[root@shell ~]#

[root@shell ~]# awk  '{print  $0}'  /etc/passwd

你将会见到/etc/passwd 文件的内容出现在眼前。现在,解释 awk 做了些什么。调用 awk时,我们指定/etc/passwd 作为输入文件。执行 awk 时,它依次对/etc/passwd 中的每一行执行 print 命令。

所有输出都发送到 stdout,所得到的结果与执行 cat /etc/passwd 完全相同。

现在,解释{ print }代码块。在 awk 中,花括号用于将几块代码组合到一起,这一点类似于 C 语言。在代码块中只有一条 print 命令。在 awk 中,如果只出现 print 命令,那么将打印当前行的全部内容。

[root@shell ~]#

[root@shell ~]# awk  -F":"  '{ print $1 }'  /etc/passwd

[root@shell ~]# awk  -F":"  '{ print $1 $3 }'  /etc/passwd

[root@shell ~]# awk  -F":"  '{ print $1 " " $3 }'  /etc/passwd

-F参数:指定分隔符,可指定一个或多个

print 后面做字符串的拼接

下面通过几实例来了解下awk的工作原理:

实例一:只查看test.txt文件(10行)内第2到第3行的内容(企业面试)

[root@shell ~]#

[root@shell ~]# touch  test.txt

[root@shell ~]# vi  test.txt

[root@shell ~]# cat  test.txt

[root@shell ~]#

[root@shell ~]# awk  '{if(NR>=2 && NR<=3) print $1}'  test.txt 

实例二:已知test.txt文件内容为  I am Poe,my qq is 33794712

[root@shell ~]# cat test.txt

I am Poe,my qq is 33794712

[root@shell ~]#

请从该文件中过滤出'Poe'字符串与33794712,最后输出的结果为:Poe 33794712

[root@shell ~]#

[root@shell ~]# awk  -F  '[ ,]+'  '{print $3" "$7}'  test.txt


BEGIN 和 END 模块

通常,对于每个输入行, awk 都会执行每个脚本代码块一次。然而,在许多编程情况中,可能需要在 awk 开始处理输入文件中的文本之前执行初始化代码。对于这种情况, awk 允许您定义一个 BEGIN 块。

因为 awk 在开始处理输入文件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。

awk 还提供了另一个特殊块,叫作 END 块。 awk 在处理了输入文件中的所有行之后执行这个块。通常, END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。

实例一:统计/etc/passwd的账户人数

[root@shell ~]#

[root@shell ~]# awk  '{count++;print $0;}  END{print "user count is ",count}'  /etc/passwd

实例二:统计某个文件夹下的文件占用的字节数

统计/usr目录下文件占用的字节数

[root@shell ~]#

[root@shell ~]# cd  /usr/

[root@shell usr]# ll  |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ",size}'

如果以M为单位显示:

[root@shell usr]# ll |awk 'BEGIN{size=0;} {size=size+$5;} END{print "[end]size is ",size/1024/1024,"M"}'


awk 运算符

awk 赋值运算符:a+5;等价于: a=a+5;其他同类

[root@shell ~]#

[root@shell ~]# awk  'BEGIN{a=5;a+=5;print  a}'                        #a+=5 等同于 a=a+5

[root@shell ~]# awk  'BEGIN{a=5;a=a+5;print a}'

10

[root@shell ~]#

awk逻辑运算符:

[root@shell ~]#

[root@shell ~]# awk 'BEGIN{a=1;b=2;print (a>2&&b>1,a=1||b>1)}'

0 1

[root@shell ~]#

awk正则运算符:

[root@shell ~]# awk  'BEGIN{a="100testaa";if(a~/100/)  {print "ok"}}'

ok

[root@shell ~]#

[root@shell ~]# echo|awk 'BEGIN{a="100testaaa"}a~/test/{print "ok"}'

ok

[root@shell ~]#

关系运算符:

如: > < 可以作为字符串比较,也可以用作数值比较,关键看操作数如果是字符串就会转换为字符串比较。两个都为数字 才转为数值比较。字符串比较:按照ascii码顺序比较。

[root@shell ~]#

[root@shell ~]# awk  'BEGIN{a="11";if(a>=9){print "ok"}}'

[root@shell ~]#

[root@shell ~]# awk  'BEGIN{a=11;if(a>=9){print "ok"}}'

ok

[root@shell ~]#

awk 算术运算符:

说明,所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0

[root@shell ~]# awk  'BEGIN{a="b";print a++,++a}'

0 2

[root@shell ~]#

[root@shell ~]# awk  'BEGIN{a="20b4";print a++,++a}'

20 22

[root@shell ~]#

这里的a++ , ++a与javascript语言一样:a++是先赋值加++;++a是先++再赋值

三目运算符 ?:

[root@shell ~]#

[root@shell ~]# awk  'BEGIN{a="b";print a=="b"?"ok":"err"}'

ok

[root@shell ~]#

[root@shell ~]# awk  'BEGIN{a="b";print a=="c"?"ok":"err"}'

err

[root@shell ~]#


常用 awk 内置变量


awk 正则

正则应用

规则表达式

awk '/REG/{action} ' file,/REG/为正则表达式,可以将$0 中,满足条件的记录送入到:action 进行处理

[root@shell ~]#

[root@shell ~]# awk  '/root/{print $0}'  /etc/passwd                          #匹配所有包含root的行

[root@shell ~]#

[root@shell ~]# awk  -F: '$5~/root/{print $0}'  /etc/passwd              #以顿号作为分隔符,匹配第5个字段是root的行

布尔表达式

awk '布尔表达式{action}' file 仅当对前面的布尔表达式求值为真时, awk 才执行代码块。

[root@shell ~]#

[root@shell ~]# awk  -F: '$1=="root"{print $0}'  /etc/passwd

[root@shell ~]# awk  -F: '($1=="root")&&($5=="root") {print $0}'  /etc/passwd

awk 的 if、循环和数组

条件语句

awk 提供了非常好的类似于 C 语言的 if 语句。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355