awk简介

本质:

是一门编程语言,有自己的语法和库函数。

工作机理:

  • 读取每一行

  • 按分隔符把这一行切成多个(不指定分隔符的话,空白或者连续空白就是分隔符)

    $1:代表第一列;$2:第二列。。。。

    $0:整行内容

  • 按需,按特定格式打印出来

功能:

  • 可以限定处理哪些行

  • 可以根据列的内容做条件分支处理

  • 可以循环所有列

  • 可以自己定义变量

命令基本用法:

awk [option] 'PROGRAM' FILE...

PROGRAME:PATERN{ACTION STATEMENTS}

例子1:/etc/fstab文件用空白分隔,打印出第二列和第四列。

列之间用逗号分隔,打印出来的列之间就有空格;不加逗号,就把这2列连一起了

[root@localhost ~]# tail -4 /etc/fstab/dev/mapper/centos-root /                       xfs     defaults        0 0UUID=3d3b316a-529e-484a-9895-e785fdde5365 /boot                   xfs     defaul/dev/mapper/centos-home /home                   xfs     defaults        0 0/dev/mapper/centos-swap swap                    swap    defaults        0 0[root@localhost ~]# tail -4 /etc/fstab | awk '{print $2,$4}'/ defaults/boot defaults/home defaultsswap defaults[root@localhost ~]# tail -4 /etc/fstab | awk '{print $2 $4}'/defaults/bootdefaults/homedefaultsswapdefaults

例子2:/etc/fstab文件用空白分隔,打印出第二列和第四列,并随意加几列

# tail -4 /etc/fstab | awk '{print "hi",$2,$4,567}'hi / defaults 567hi /boot defaults 567hi /home defaults 567hi swap defaults 567

由上面2个小例子,可以看出awk的基本使用要点:

  • print的项目间,加了逗号,打印出来的项目之间就有空格

  • print后面的内容,可以是列号,自己定义的变量,随意的字符串和数字

  • print后面如果省略项目,就是打印$0

选项

  • -F:告诉awk用什么分隔符,去分隔输入

  • -v:自定义变量。var=value。定义多个变量要使用多次-v

awk的变量

1,内置变量

  • FS:input file seperator 输入列分隔符,默认是空白或者连续空白

    # tail -4 /etc/fstab | awk -v OFS=',' '{print $3,$4}'xfs,defaultsxfs,defaultsxfs,defaultsswap,defaults
  • OFS:output file seperator 输出列分隔符,默认是空白或者连续空白

    # tail -4 /etc/passwd | awk -v FS=':' '{print $1,$4}'us3 1002user100 1003user101 1004apache 48
# tail -4 /etc/passwd | awk -v FS=':' -v OFS=':' '{print $1,$4}'us3:1002user100:1003user101:1004apache:48
  • RS:input record seperator 输入行识别符,默认是回车

  • ORS:output record seperator 输出行识别符,默认是回车

  • NF:每行里列的数量

    在awk内部引用变量不需要加$。

    # awk '{print NF}' /etc/fstab01210191216666
  • NR:文件的行号

    # awk '{print NR}' /etc/fstab123456789101112

    如果是多个文件,则连续计数行号。

    # awk '{print NR}' /etc/fstab /etc/issue123456789101112131415
  • FNR:如果是多个文件,则单独计数行号。

    # awk '{print FNR}' /etc/fstab /etc/issue123456789101112123
  • FILENAME:显示文件名

    # awk '{print FILENAME}' /etc/fstab /etc/issue/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/issue/etc/issue/etc/issue
  • ARGC:命令行参数的个数

  • ARGV:数组,保存的是接收到的命令行参数。

    # awk '{print ARGC, ARGV[0],ARGV[1],ARGV[2]}' /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue# awk 'BEGIN{print ARGC, ARGV[0],ARGV[1],ARGV[2]}' /etc/fstab /etc/issue3 awk /etc/fstab /etc/issue

2,自定义变量

变量名区分大小写,可以使用-v定义;也可以在PROGRAM体里定义。什么是PROGRAM,在大括号里的部分。PROGRAME里的多个语句,使用分号分隔。

  • 使用-v定义变量

    # awk -v var="122dd" '{print var}' /etc/issue122dd122dd122dd
  • 在在PROGRAM体里定义变量

    # awk '{var="11d";print var}' /etc/issue11d11d11d

printf语句用法

实现格式化输出。不自动换行,使用\n是换行。

格式符:

  • %c:显示ascii码

  • %d,%i:显示十进制整数

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

  • %f:显示浮点数

  • %g, %G:显示科学计数法或浮点数

  • %s:显示字符串

  • %u:显示无符号整数

  • %%:显示%自身

# awk -F: '{printf "username:%s,uid:%d\n",$1,$3}' /etc/passwdusername:avahi,uid:70username:postfix,uid:89

修饰符:

  • 数字1[.数字2]

  • -数字1[.数字2]:左对齐

  • +数字1[.数字2]:显示数字的符号,正数显示+,符号显示-

数字1:显示时,列所占用的宽度。默认是右对齐,-号是左对齐。

数字2:有小数点的话,指定显示几位小数。

# awk -F: '{printf "username:%15s,uid:%d\n",$1,$3}' /etc/passwdusername:        user101,uid:1004username:         apache,uid:48# awk -F: '{printf "username:%-15s,uid:%d\n",$1,$3}' /etc/passwdusername:user100        ,uid:1003username:user101        ,uid:1004username:apache         ,uid:48

操作符

1,算术操作符

a+b,a-b,a*b,a/b,a^b,a%b,

2,字符串操作符

没有操作符,就是连接字符串

3,赋值操作符

=,+=,-=,*=,/=,%=,^=

++,--

4,比较操作符

>,>=,<,<=,!=,==

5,模式匹配符

~:左侧的字符串是否能被右侧的模式所匹配

!~:左侧的字符串是否能被右侧的模式所不匹配

6,逻辑操作符

&&,||,!

7,函数调用

function_name(arg1,arg2...)

8,条件表达式

selector?true:false

例子:uid大于等于1000的是aa。

# awk -F: '{$3>=1000?ut="aa":ut="bb"; printf "%s:%d\n", ut, $3}'\n /etc/passwd

PATTERN

选择要处理的行,不写pattern默认是处理所有行。

1,/正则表达式/:仅把被匹配到的行作为处理对象

仅处理UUID开头的行

# awk -F' ' '/^UUID/{print $1, $3}'\n /etc/fstabUUID=3d3b316a-529e-484a-9895-e785fdde5365 xfs

a仅处理不以UUID开头的行

# awk -F' ' '!/^UUID/{print $1, $3}'\n /etc/fstab### by## filesystems,# man#/dev/mapper/centos-root xfs/dev/mapper/centos-home xfs/dev/mapper/centos-swap swap

2,关系表达式:结果为真的行,才是处理对象。结果是非0或非空白都是真。

处理uid大于等于1000的行

# awk -F: '$3>=1000{print $1,$3}' /etc/passwdnfsnobody 65534us1 1001us3 1002user100 1003user101 1004

处理shell是bash的行

最后一列的字符串包含bash的行# awk -F: '$NF~"bash"{print $1,$NF}' /etc/passwdroot /bin/bashys /bin/bashus1 /bin/bashus3 /bin/bashuser100 /bin/bashuser101 /bin/bash最后一列的字符串以bash结尾的行# awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwdroot /bin/bashys /bin/bashus1 /bin/bashus3 /bin/bashuser100 /bin/bashuser101 /bin/bash# awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwdroot /bin/bashys /bin/bashus1 /bin/bashus3 /bin/bashuser100 /bin/bashuser101 /bin/bash

指定处理的行号

# awk -F: 'NR>=1&&NR<=3{print $1,$NF}' /etc/passwdroot /bin/bashbin /sbin/nologindaemon /sbin/nologin

指定处理的开始行,终了行,但不是用数字,而是用pattern

# awk -F: '/^root/,/^daemon/{print $1,$NF}' /etc/passwdroot /bin/bashbin /sbin/nologindaemon /sbin/nologin

3,BEGIN,END

  • BEGIN:处理第一行前,执行一次BEGIN。一般用于打印表头。

  • END:处理完最后一行后,执行一次END。一般用于打印汇总。

# awk -F: 'BEGIN{print "    username      uid"} {print $1,$3}' /etc/passwd    username      uidroot 0bin 1daemon 2

打印出前5行的username和uid,并在结尾统计出:uid之和

# awk -F: -v sum=0 'BEGIN{print "username  uid"} NR>=1&&NR<=5{printf "%8s  %3d\n", $1,$3;sum+=$3} END{printf "       sum:%s\n",sum}' /etc/passwdusername  uid    root    0     bin    1  daemon    2     adm    3      lp    4       sum:10

常用的action

1,控制语句

  • if(condition) {...}

    仅显示uid大于等于1000的行。

    # awk -F: '{ if($3>=1000) {print $1,$3}}' /etc/passwdnfsnobody 65534ys 1000us1 1001us3 1002user100 1003user101 1004
  • if(condition) {...} else {...}

    # awk -F: '{ if($3>=1000) {printf "user:%s\n",$1} else {printf "suser:%s\n",$1} }' /etc/passwdsuser:rootuser:nfsnobody

    例子:统计磁盘使用量超过10%的分区。

    按空格分隔,用第五列做判断,第五列是Use%,17%,0%等,可以直接和10作比较。

    其实原理是字符串比较,字母的ASCII码大于数字,所以第一行也显示出来了,完美实现要求。

    # df -hFilesystem               Size  Used Avail Use% Mounted on/dev/mapper/centos-root   38G  6.1G   31G  17% /devtmpfs                 1.9G     0  1.9G   0% /devtmpfs                    1.9G     0  1.9G   0% /dev/shmtmpfs                    1.9G  9.0M  1.9G   1% /runtmpfs                    1.9G     0  1.9G   0% /sys/fs/cgroup/dev/sda1               1014M  179M  836M  18% /boot/dev/mapper/centos-home   19G   40M   19G   1% /hometmpfs                    379M     0  379M   0% /run/user/0# df -h | awk '{if($5>"10") print $0}'Filesystem               Size  Used Avail Use% Mounted on/dev/mapper/centos-root   38G  6.1G   31G  17% //dev/sda1               1014M  179M  836M  18% /boot
  • switch(expression){case val1 or /pattern/: 语句; case val1 or /pattern/ 语句; ... default: 语句}

    val是固定的值;pattern是正则表达式。

  • while(condition) {...}

    统计/etc/fstab文件,U和/开头的行是处理对象。把每列的字符串的长度算出来,显示在列的后面,中间用冒号分隔。循环到最后一列时,打印换行。

    # awk '/^[U\/]/{i=1;while(i<=NF) { printf "%s:%d ",$i,length($i); if(i==NF) {printf "\n"} i++} }' /etc/fstab/dev/mapper/centos-root:23 /:1 xfs:3 defaults:8 0:1 0:1UUID=3d3b316a-529e-484a-9895-e785fdde5365:41 /boot:5 xfs:3 defaults:8 0:1 0:1/dev/mapper/centos-home:23 /home:5 xfs:3 defaults:8 0:1 0:1/dev/mapper/centos-swap:23 swap:4 swap:4 defaults:8 0:1 0:1
  • do{...} while(condition)

  • for(expr1;expr2;expr3){...}

    统计/etc/fstab文件,U和/开头的行是处理对象。把每列的字符串的长度算出来,显示在列的后面,中间用冒号分隔。循环到最后一列时,打印换行。

    # awk '/^[U\/]/{for(i=1;i<=NF;i++) { printf "%s:%d ",$i,length($i); if(i==NF) {printf "\n"} } }' /etc/fstab/dev/mapper/centos-root:23 /:1 xfs:3 defaults:8 0:1 0:1UUID=3d3b316a-529e-484a-9895-e785fdde5365:41 /boot:5 xfs:3 defaults:8 0:1 0:1/dev/mapper/centos-home:23 /home:5 xfs:3 defaults:8 0:1 0:1/dev/mapper/centos-swap:23 swap:4 swap:4 defaults:8 0:1 0:1

    遍历数组的特殊用法:for(var in array)

  • continue,bread[n](退出哪层循环)

  • next:提前退出当前行的处理,直接进入下一行。类似continue。

    显示uid是偶数的行。

    # awk -F: '{ if($3%2)next;print $1,$3}' /etc/passwdroot 0daemon 2lp 4shutdown 6
  • delete arrary[index]:删除数组的某个元素

  • delete array:删除数组

  • exit:退出

2,input statements

3,output statements

数组

  • 索引数组:索引是数字

  • 关联数组:索引是任意的字符串,字符串要用双引号括起来。

当引用一个不存在的数组元素时,会自动创建之。数组索引是从1开始。

判断某个索引是否存在,要使用特殊的语法:index in array

第一个wk["tur"]=12222a的12222a没有用双引号括起来,打印wk["tur"]的值变成了12222,自动把a去掉了。

# awk 'BEGIN{wk["mon"]="aaa";wk["tur"]=12222a; print wk["tur"]; print wk["mon"]}'12222aaa[root@localhost ~]# awk 'BEGIN{wk["mon"]="aaa";wk["tur"]="1222a"; print wk["tur"]; print wk["mon"]}'12222aaaa

用for遍历数组,i是数组的索引,而不是数组元素的值。

# awk 'BEGIN{wk["mon"]="aaa";wk["tur"]="12222a"} {for(i in wk)print i}' /etc/issueturmonturmonturmon[root@localhost ~]# awk 'BEGIN{wk["mon"]="aaa";wk["tur"]="12222a"} {for(i in wk)print wk[i]}' /etc/issue12222aaaa12222aaaa12222aaaa

统计每个状态出现的次数之和。

# netstat -tanActive Internet connections (servers and established)Proto Recv-Q Send-Q Local Address           Foreign Address         Statetcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTENtcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTENtcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTENtcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTENtcp        0      0 127.0.0.1:6011          0.0.0.0:*               LISTENtcp        0     64 192.168.56.107:22       192.168.56.1:60328      ESTABLISHEDtcp6       0      0 :::111                  :::*                    LISTENtcp6       0      0 :::80                   :::*                    LISTENtcp6       0      0 :::22                   :::*                    LISTENtcp6       0      0 ::1:631                 :::*                    LISTENtcp6       0      0 ::1:6011                :::*                    LISTEN# netstat -tan | awk '{if(NR==1 || NR==2)next; wk[$6]++} END{for(i in wk) printf "%s:%d times\n", i,wk[i]}'LISTEN:10 timesESTABLISHED:1 times

函数

1,内置函数

  • rand():随机返回小于1的小数

  • split(要被分隔的串,存放分隔后的结果,分隔符):分隔字符串。

    # netstat -tnl | awk '/^tcp\>/{split($4,ip,":"); print ip[1]}'0.0.0.0192.168.122.10.0.0.0127.0.0.1127.0.0.1

2,也支持自定义函数

# c/c++ 学习互助QQ群:877684253![](https://img2018.cnblogs.com/blog/1414315/201811/1414315-20181106214320230-961379709.jpg)# 本人微信:xiaoshitou5854

(0)

相关推荐

  • 如何在/etc/fstab中正确挂载NTFS分区?

    如何在/etc/fstab中正确挂载NTFS分区? 2018-11-21 10:54 automount, fstab, ubuntu, 许可 问题描述 经过一个令人讨厌的事件(我的第二个,你认为 ...

  • linux bash算术运算和条件语句

    +, -, *(乘), /(除), **(乘方), %(取模) let var=算术运算符表达式 高级let用法:let i+=2 +=,-=,*=,/=,%=,**= 自增:let var++ va ...

  • linux 文件系统管理三部曲之三:挂载文件系统

    上面说明了,硬盘的划分和格式化,那么怎么使用,还没说,这里说一下,怎么使用创建好的文件系统. 使用文件系统 只要把文件系统"挂载"到某个目录上,就可以通过这个目录访问文件系统了. ...

  • 文本处理工具awk

    文本处理工具awk awk:(Aho, Weinberger, Kernighan,)报告生成器,格式化文本输出 有多种版本:New awk(nawk),GNU awk( gawk) [toc]## ...

  • centos6 自动挂载ntfs格式u盘、iso文件

    /etc/fstab文件的作用 磁盘被手动挂载之后都必须把挂载信息写入/etc/fstab这个文件中,否则下次开机启动时仍然需要重新挂载. 系统开机时会主动读取/etc/fstab这个文件中的内容,根 ...

  • 我这里整理了一个关于中药剂量的一个常识的简介,分享给各位朋友。

    关于度量:秦始皇统一六国,统一度量衡,但是通过中医的学习会发现度量衡还是很混乱,半斤八两,那么一两是多少呢?还有论钱论厘的,有的说一小勺,有的说一小杯,有的说一小碗,你怎么弄?我这里整理了一个关于中药 ...

  • 趋势丨蔗糖理想替代品——阿洛酮糖简介

    导语 作为蔗糖的理想替代品,阿洛酮糖是什么?有何特点? 文:中国食品报网丨欣文 图:Stockfood 我们曾分享过一篇关于甜味剂的解读文章,对甜味剂的优点及工业应用进行了介绍,指出世界范围内无糖和低 ...

  • 李默飞个人简介

    易学是我国劳动人民智慧的结晶,是一门古老的学科,自古就充满了无限的神秘,一直是人们不断探索和研究的学科.古往今来有无数名人都在易学上有突出成就,如谷鬼子.诸葛亮.袁天罡等名人.近当代更是涌现出数不胜数 ...

  • 冉龙清老师个人简介

    国际易学联盟副主席 四川易经协会名誉会长 中华易经风水学院常务院长 中国易经协会会员 四川周易研究院副院长 本人于五十年代中期出生于寺庙林立的大巴山中麓,其间多有大贤隐士深隐于此.上小学初中适逢&qu ...

  • 人MTHFR基因多态性检测试剂盒(荧光PCR法)简介

    产品介绍 [注册证编号]:国械注准20173403239 [产品规格]:30人份/盒 [存储条件]:1.-20±3℃避光保存,有效期10个月 2.试剂盒在-16℃~8℃的温度范围内运输,运输时间不超过 ...

  • 迁移学习——入门简介

    一.简介 背景:现如今数据爆炸: 对机器学习模型来说要求快速构建,强泛化 对于数据来说,大部分数据没有标签 所以收集标签数据和从头开始构建一个模型都是代价高昂的,需要对模型和带有标签的数据进行重用 传 ...

  • 馆藏 明代著名画家,传世山水画作及个人生平简介

    明 沈周 纵193.8X横98厘米 台北故宫博物院藏 沈周(1427-1509)吴门四家之首.字启南,号石田,更号白石翁.长州人.世代隐居吴门.他凭借想象描绘庐山为他的老师陈宽作寿.在画法上宗学王蒙, ...

  • 木醋杆菌简介

    醋杆菌属(学名:Acetobacter)是乙酸细菌的一个属,其特点是能够在有空气的条件下将乙醇转化为乙酸.醋酸杆菌属包含有多个种.很多其它的细菌也能在不同的条件下产生乙酸,但醋酸杆菌属中的细菌只在这一 ...

  • SunnyUI 学习1.1——简介与界面布局的使用

    SunnyUI 学习1.1--简介与界面布局的使用 炎黄子孙__ 2021-01-01 14:59:26  3015  收藏 12 分类专栏: SunnyUI C# winform 文章标签: c# ...