简介

awk是一个强大的文本分析工具,相对于grep的查找,sed的行编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

命令格式和选项

格式

# awk [options] 'script' file1 file2, ...
# awk [options] 'PATTERN { action }' file1 file2, ...

命令选项

  • -F fs or --field-separator fs:指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
  • -v var=value or --asign var=value:赋值一个用户定义变量。
  • -f scripfile or --file scriptfile:从脚本文件中读取awk命令。

print输出

使用格式

print item1, item2, ...

要点
1.各项目之间使用逗号隔开,而输出时则以空白字符分隔;
2.输出的item可以为字符串或数值、当前记录的字段(如$1)、变量或awk的表达式;数值会先转换为字符串,而后再输出;
3.print命令后面的item可以省略,此时其功能相当于print $0, 因此,如果想输出空白行,则需要使用print "";
举例

# awk 'BEGIN{print "one line.\ntwo line."}'
one line.
two line.
# awk -F : '{print $1"-->"$7}' /etc/passwd |head -1
root-->/bin/bash
# awk -F : '{print $1,$7}' /etc/passwd |head -1
root /bin/bash

awk内置变量

记录变量

  • FS:读取文件本时,所使用字段分隔符,默认是任何空格;
  • RS:输入文本信息所使用的换行符,默认是一个换行符;
  • OFS:输出字段分隔符(默认值是一个空格)。
  • ORS:输出记录分隔符(默认值是一个换行符)。

数据变量

  • NR:awk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数;
  • NF:当前记录的field个数;
  • FNR:与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数;
  • ARGV:数组,保存命令行本身这个字符串,如awk '{print $0}' a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt;
  • ARGC:awk命令的参数的个数;
  • FILENAME:awk命令所处理的文件的名称;
  • ENVIRON:当前shell环境变量及其值的关联数组;

举例

# awk -F : '{print $1,$NF}' /etc/passwd |head -1
root /bin/bash
# awk 'BEGIN {FS=":"} {print $1,$NF}' /etc/passwd |head -1
root /bin/bash
# awk 'BEGIN {FS=":";OFS="-->"} {print $1,$NF}' /etc/passwd |head -1
root-->/bin/bash
# awk 'BEGIN {RS=" "} {print $0}' /etc/passwd
# awk 'BEGIN {ORS="@@@"} {print $0}' /etc/passwd
# awk '{print NR,$0}' /etc/issue /etc/redhat-release
1 \S
2 Kernel \r on an \m
3
4 CentOS Linux release 7.2.1511 (Core)
# awk '{print FNR,$0}' /etc/issue /etc/redhat-release
1 \S
2 Kernel \r on an \m
3
1 CentOS Linux release 7.2.1511 (Core)

自定义变量

gawk允许用户自定义自己的变量以便在程序代码中使用,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头。gawk变量名称区分字符大小写。

脚本中

在gawk中给变量赋值使用赋值语句进行,例如:

# awk 'BEGIN{var="variable testing";print var}'

命令行

gawk命令也可以在“脚本”外为变量赋值,并在脚本中进行引用。例如,上述的例子还可以改写为:

# awk -v var="variable testing" 'BEGIN{print var}'

printf

printf命令的使用格式:

printf format, item1, item2, ...

要点

1.其与print命令的最大不同是,printf需要指定format;
2.format用于指定后面的每个item的输出格式;
3.printf语句不会自动打印换行符;\n

format格式的指示符都以%开头,后跟一个字符;如下:

  • %c: 显示字符的ASCII码;
  • %d, %i:十进制整数;
  • %e, %E:科学计数法显示数值;
  • %f: 显示浮点数;
  • %g, %G: 以科学计数法的格式或浮点数的格式显示数值;
  • %s: 显示字符串;
  • %u: 无符号整数;
  • %%: 显示%自身;

修饰符

  • N: 显示宽度;
  • -: 左对齐;
  • +:显示数值符号;

举例

# awk -F : '{printf "%-20s %s\n",$1,$NF}' /etc/passwd |head -1
root /bin/bash

输出重定向

格式

print items > output-file
print items >> output-file
print items | command

特殊文件描述符

/dev/stdin:标准输入
/dev/sdtout: 标准输出
/dev/stderr: 错误输出
/dev/fd/N: 某特定文件描述符,如/dev/stdin就相当于/dev/fd/0;

操作符

算术

  • -x: 负值
  • +x: 转换为数值;
  • x^y:
  • x**y: 次方
  • x*y: 乘法
  • x/y:除法
  • x+y:
  • x-y:
  • x%y:

字符串操作符

只有一个,而且不用写出来,用于实现字符串连接;

赋值操作符

  • =
  • +=
  • -=
  • *=
  • /=
  • %=
  • ^=
  • **=
  • ++
  • --

需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,应以/[=]/替代;

布尔值

awk中,任何非0值或非空字符串都为真,反之就为假;

比较操作符

  • x < y True if x is less than y.
  • x <= y True if x is less than or equal to y.
  • x > y True if x is greater than y.
  • x >= y True if x is greater than or equal to y.
  • x == y True if x is equal to y.
  • x != y True if x is not equal to y.
  • x ~ y True if the string x matches the regexp denoted by y.
  • x !~ y True if the string x does not match the regexp denoted by y.
  • subscript in array True if the array array has an element with the subscript subscript.

表达式间的逻辑关系符

  • &&
  • ||

条件表达式

  • selector?if-true-exp:if-false-exp

函数调用

  • function_name(para1,para2)

常见的模式类型

1.Regexp: 正则表达式,格式为/regular expression/
2.expresssion: 表达式,其值非0或为非空字符时满足条件,如:$1 ~ /foo/ 或 $1 == "magedu",用运算符(匹配)和!(不匹配)。
3.Ranges: 指定的匹配范围,格式为pat1,pat2
4.BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次
5.Empty(空模式):匹配任意输入行;

/正则表达式/:使用通配符的扩展集。
关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。
模式匹配表达式:
模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。
BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。
END:让用户在最后一条输入记录被读取之后发生的动作。

举例

# awk -F : '$3==1000{print $0}' /etc/passwd
fei:x:1000:1000::/home/fei:/bin/bash
# awk -F : '$1~/^f/{print $0}' /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
fei:x:1000:1000::/home/fei:/bin/bash

常见的Action

1.Expressions
2.Control statements:if, while等;
3.Compound statements:组合语句;
4.Input statements
5.Output statements

控制语句

if-else

语法

if (condition) {then-body} else {[ else-body ]}

举例

# awk -F: '{if ($3==0) {print $1, "Adminitrator";} else { print $1,"Common User"}}' /etc/passwd
# awk -F: '{if ($1 ~ /root/) {print $1,"is Administrator"}else {print $1,"is common"}}' /etc/passwd
# awk -F: '{if ($1 == "root") {printf "%18s %s\n",$1,"Admin"}else {printf "%18s %s\n",$1,"common"}}' /etc/passwd
# awk -F: -v sum=0 '{if ($3<1000) sum++}END{print sum}' /etc/passwd

while

语法

while (condition){statement1; statment2; ...}

举例

# awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd
# awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd

do-while

语法

do {statement1, statement2, ...} while (condition)

举例

# awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd
# awk -F: '{i=4;do {print $i;i--}while(i>4)}' /etc/passwd

for

语法

for ( variable assignment; condition; iteration process) { statement1, statement2, ...}

举例

# awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd
# awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd

case

语法

switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...}

break 和 continue

常用于循环或case语句中

next

提前结束对本行文本的处理,并接着处理下一行;例如,下面的命令将显示其ID号为奇数的用户:

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

awk中使用数组

语法

array[index-expression]

index-expression可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array的方式。
要遍历数组中的每一个元素,需要使用如下的特殊结构:

for (var in array) { statement1, ... }

其中,var用于引用数组下标,而不是元素值;
举例

# awk 'BEGIN{a["mon"]="Monday";a["sun"]="Sunday";print a["mon"]}'
Monday
# awk 'BEGIN{a["mon"]="Monday";a["sun"]="Sunday";print a["sun"]}'
Sunday

统计系统的用户默认shell出现次数:

# awk -F: '{BASH[$NF]++}END{for (i in BASH){printf "%15s %d\n",i,BASH[i]}}' /etc/passwd
/bin/sync 1
/bin/bash 2
/sbin/nologin 18
/sbin/halt 1
/sbin/shutdown 1

统计系统的网络连接状态的次数:

netstat -tan|awk '/^tcp\>/{state[$NF]++}END{for (a in state){printf "%15s %d\n",a,state[a]}}'

统计httpd日志中访问量前十的IP地址的访问次数:

 awk '{ip[$1]++}END{for (i in ip){printf "%18s %d\n",i,ip[i]}}' access_20170119.log |sort -k2 -rn|head

统计日志中各状态码的访问次数:

 awk '{ip[$9]++}END{for (i in ip){printf "%5s %d\n",i,ip[i]}}' access_20170119.log |sort  -k2 -rn|head

统计每个用户的进程的占了多少内存(注:sum的RSS那一列):

ps aux |awk 'NR!=1{user[$1]+=$6}END{for (i in user){print i,user[i]}}'
polkitd 11804
dbus 1868
postfix 7804
root 114984

内置函数

spilt

用法

split(string, array [, fieldsep [, seps ] ])

功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从1开始的序列;
举例
显示连接服务器中IP最多的10个:

netstat -tan|awk '/:80\>/{split($5,clients,":");IP[clients[4]]++}END{for (i in IP){printf "%20s %d\n",i,IP[i]}}' |sort -k2 -rn |head

显示系统中磁盘空间使用超过20%的分区:

df -lh | awk '!/^File/{split($5,percent,"%");if(percent[1]>=20){print $1}}'

统计当前系统上每个客户端IP的连接中处于TIME_WAIT的连接状态的个数:

 netstat -tan |awk '/TIME_WAIT/{split($5,clients,":");IP[clients[4]]++}END{for (i in IP){printf "%20s %d\n",i,IP[i]}}' |sort -k2 -rn |head

统计ps aux命令执行时,当前系统上各状态的进程的个数:

ps aux |awk '!/^USER/{state[$8]++}END{for (i in state){printf "%10s %d\n",i,state[i]}}' |sort -k2 -rn

统计ps aux命令执行时,当前系统上各用户的进程的个数:

 ps aux |awk '!/^USER/{state[$1]++}END{for (i in state){printf "%10s %d\n",i,state[i]}}' |sort -k2 -rn

显示ps aux命令执行时,当前系统上其VSZ(虚拟内存集)大于10000的进程及其PID:

 ps aux|awk '!/^USER/{if ($5>10000) print $2,$5,$NF}'

length

length([string])

功能:返回string字符串中字符的个数;

substr

substr(string, start [, length])

功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;

system

system(command)

功能:执行系统command并将结果返回至awk命令

扩展学习

http://www.cnblogs.com/repository/archive/2011/05/13/2045927.html
http://www.runoob.com/linux/linux-comm-awk.html
http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html
http://coolshell.cn/articles/9070.html

awk.md的更多相关文章

  1. 一些我后写出来的awk脚本

    mail.awk function mailByShell(receiver, sender, subject, content, __ARGVEND__, xhead, xfrom, xmime, ...

  2. awk 实战

    awk 一些好玩的用法.有什么不错的点子可以留言,发挥出awk牛逼功能 分离mac地址 ifconfig wlan0 | grep eth | awk '{n=split($2,arr,": ...

  3. shell编程之awk命令详解

    shell编程之awk命令详解 a:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; out ...

  4. Linux基础命令-Nginx-正则表达式( grep sed awk )-Shell Script--etc

    Linux基础使用 学习内容博客 内存 查看swap分区信息 > swapon -s 添加swap分区 > mkswap /dev/sdb2 > 激活 swapon -a /dev/ ...

  5. [svc]find+xargs/sed&sed后向引用+awk多匹配符+过滤行绝招总结&&产生随机数

    30天内的文件打包 find ./test_log -type f -mtime -30|xargs tar -cvf test_log.tar.gz find,文件+超过7天+超过1M的+按日期为文 ...

  6. [svc]linux常用手头命令-md版-2017年11月12日 12:31:56

    相关代码 curl命令-网站如果3次不是200或301则报警 curl -o /dev/null -s -w "%{http_code}" baidu.com -k/--insec ...

  7. 好用的Markdown编辑器一览 readme.md 编辑查看

    https://github.com/pandao/editor.md https://pandao.github.io/editor.md/examples/index.html Editor.md ...

  8. awk命令简介

    awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各 ...

  9. awk使用说明

    原文地址:http://www.cnblogs.com/verrion/p/awk_usage.html Awk使用说明 运维必须掌握的三剑客工具:grep(文件内容过滤器),sed(数据流处理器), ...

随机推荐

  1. Windows2012开机启动项设置

    最简单方式 开始->运行->输入shell:startup 在打开的启动文件夹中,将需要启动程序的快捷方式复制进去,完工 重启试试吧 https://blog.csdn.net/tmton ...

  2. JavaWeb项目WebContent下的资源文件无法引用

    JavaWeb项目引用资源的时候尽量使用绝对路径. 作者在帮助同学完善其JavaWeb项目端页面的时候,css样式文件怎么也引用不了. 第一个想到的是:是不是文件路径写错了? 于是,作者换了绝对路径, ...

  3. [Linux] Linux系统(用户管理)

    Linux中有三种用户 Root用户:超级管理员 系统用户:Linux运行某些程序所必需的用户,不建议修改 普通用户:一般修改这个 使用命令groupadd,添加用户组,参数:组名称 在文件/etc/ ...

  4. 啰里吧嗦jvm

    一.为什么要了解jvm 有次做项目的时候,程序run起来的时候,总是报OutOfMemoryError,有老司机教我们用jconsole.exe看内存溢出问题 就是这货启动jconsole后,发现一个 ...

  5. 微信小程序,关于设置data里面的数据。

    关于设置 data里面的数据 wxml: <view>{{userName}}</view> data: { userName:'张三', } 有两种方法 方法一:直接使用点关 ...

  6. 使用postman测试接口时需要先登录怎么办

    原文 1.在浏览器上先登录,登录成功后获取cookie: 2.接着打开postman:

  7. 在IIS7中应用Application Request Routing配置反向代理

    配置反向代理软件.zip 开启Proxy项: 该设置表面只有HTTP_HOST为phpweb.leven.com.cn的URL才能通过该规则,如果您绑定了多个域名,可以根据多次增加或者通过正则表达式的 ...

  8. springboot项目的重定向和转发

    下面是idea软件创建的项目目录,这里总结了一下转发与重定向的问题,详解如下. 首先解释一下每个文件夹的作用,如果你是用的是idea创建的springboot项目,会在项目创建的一开始resource ...

  9. cordova打包安卓或IOS应用

    1,先搞个java jdk.我先用的1.7版本的,用cordova打包的时候各种报错,应该是向下不兼容吧.又换了个1.8版本.装jdk一定要注意jdk跟jre不能都装在目标文件夹的根目录下,jdk跟j ...

  10. <Android 基础(二十五)> Frame Animation

    简介 Frame Animation, 逐帧动画,通过定义一系列的Drawable对象来实现动画效果,可以用来作为视图的背景. Frame Animation在代码中体现为AnimationDrawa ...