awk

一、awk简介

awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。

awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。

如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。

awk分别代表其作者姓氏的第一个字母。因为它的作者是三个人,分别是Alfred Aho、Brian Kernighan、Peter Weinberger。

gawk是awk的GNU版本,它提供了Bell实验室和GNU的一写扩展。



二、awk的两种形式语法格式

awk  [options]  'commands'  filenames

awk [options]  -f  awk-script-file  filenames

options(选项):

-F  对每次处理的内容,指定一个子定义的分隔符,默认的分隔符是空白字符 (空格或 tab 键)

command:

BEGIN{}             {}              END{}

行处理前         行处理       行处理后

注释:(BEGIN / END)

使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文本开始执行。END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态

示例:

# awk   'BEGIN{print 1/2} {print "ok"} END{print "-----------"}' /etc/hosts

0.5

ok

ok

ok

-----------



三、awk工作原理

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

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

(2)然后,行被:(默认为空格或制表符)分解成字段(或域),每个字段存储在已编号的变量中,从$1开始,最多达100个字段

(3)awk如何知道用空格来分隔字段的呢? 因为有一个内部变量FS来确定字段分隔符。初始时,FS赋为空格

(4)awk打印字段时,将以设置的方法使用print函数打印,awk在打印的字段间加上空格,因为$1,$3之间有一个逗号。逗号比较特殊,它映射为另一个内部变量,称为输出字段分隔符OFS,OFS默认为空格

(5)awk输出之后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕



记录与字段相关内部变量:man awk

$0 :awk变量 $0 保存当前正在处理的行内容

NR :当前正在处理的行是 awk 总共处理的行号。

FNR:当前正在处理的行在其文件中的行号。

NF :每行被处理时的总字段数

$NF: 当前处理行的分隔后的最后一个字段的值

FS :输入行时的字段分隔符,默认空格

OFS  输出字段分隔符,默认是一个 空格

RS :输入记录分隔符,默认为换行符。

ORS:输出记录分隔符, 默认是换行符

区别:

字段分隔符: FS OFS  默认空格或制表符

记录分隔符: RS ORS 默认换行符



格式化输出

print 函数

# awk  -F:'{print  "username is:"  $1 "\t uid is:"  $3}'  /etc/passwd

# awk  -F: '{print  "\tusername and uid: " $1,$3 "!"}'  /etc/passwd

printf 函数

# awk -F:  '{printf  "%-15s %-10s %-15s\n", $1, $2, $3}' /etc/passwd

# awk -F: '{printf  "|%-15s |%-10s |%-15s |\n",  $1, $2, $3}' /etc/passwd

• %s  字符类型

• %d  十进制整数

• %f   浮点类型

%-15s  占15字符 - 表示左对齐,默认是右对齐

• printf 默认不会在行尾自动换行,换行加 \n

示例:

| 是分割线

四、awk模式和动作

任何awk语句都由模式动作组成。

模式部分 决定 动作语句 何时触发及触发事件。

如果省略模式部分,动作将时刻保持执行状态。

模式可以是任何条件语句 或 复合语句 或 正则表达式

模式包括两个特殊字段 BEGINEND


正则表达式:

/    /  正则需要写在双斜线内

整行匹配

awk  '/^root/'  /etc/passwd            #以root开头的

awk  '$0 ~ /^root/'  /etc/passwd        

awk  '! /^root/'  /etc/passwd            #不以root开头的

awk  '$0 !~ /^root/'  /etc/passwd     

字段匹配

# awk -F: '$1 ~ /^alice/'  /etc/passwd    

# awk -F: '$NF !~ /bash$/'  /etc/passwd    

比较表达式:

比较表达式采用对文本进行比较,只有当条件为真,才执行指定的动作。比较表达式使用关系运算符,用于比较数字与字符串。

关系运算符

运算符                     用法

< 小于                      x<y

> 大于                      x>y

<= 小于或等于         x<=y

== 等于                    x==y

!= 不等于                 x!=y

>= 大于等于             x>=y

示例:

# awk -F: '$3 == 0' /etc/passwd

# awk -F: '$3 < 10' /etc/passwd

条件表达式:

# awk -F: '$3>300 {print $0}' /etc/passwd

# awk -F: '{ if($3>300) print $0 }' /etc/passwd

# awk -F: '{ if($3>300){print $0}}' /etc/passwd

# awk -F: '{ if($3>300){print $3}else{print $1}}' /etc/passwd

算术运算:+ - * / %(模) ^(幂2^3)

可以在模式中执行计算,awk都将按浮点数方式执行算术运算

# awk -F: '$3 * 10 > 500'  /etc/passwd

# awk -F: '{  if($3*10>500) {print $0} }'  /etc/passwd

逻辑操作符和复合模式

&&          逻辑与(并且)         a&&b 

||             逻辑或                    a||b

!              逻辑非(取反)            !a

# awk -F: '$1~/root/ && $3<=15'  /etc/passwd

# awk -F: '$1~/root/ || $3<=15'  /etc/passwd

# awk  '$0 !~ /root/'  /etc/passwd  

范围模式

/ 起始表达式 /  ,  / 终止表达式 /       # 模式之间用逗号 , 隔开

# awk '/root/ , /mail/'  /etc/passwd



五、awk脚本编程

条件判断语句

if 语句

格式    { if (表达式)  {语句; 语句; ...} }

# 统计系统级别用户的数量

# awk -F: '{if($3>0 && $3<1000){count++;}}  END{print count}'  /etc/passwd

输出: 22

if...else 语句

格式    { if(表达式){语句;语句;...}else{语句;语句;...} }

# 统计出uid=0的用户,如果uid !=0则输出用户名和uid

# awk -F: '{ if($3==0){print $1} else {print $1,$3}}'  /etc/passwd

if...else if...else 语句

格式    if(表达式1) {语句;语句;...} else if (表达式2) {语句;语句;...} else if(表达式3){语句;语句;...} else {语句;语句;...} }

# awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print i; print k; print j}' /etc/passwd


awk使用外部变量

awk   参数 -v

echo "unix script" |awk -v var="bash" 'gsub(/unix/,var)'

bash script

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