Linux下的AWK入门教程 |
本文标签:Linux,AWK 简介 awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本 。 awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母 。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言” 。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能 。
使用方法 awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作 。完整的awk脚本通常用来格式化文本文件中的信息 。 通常,awk是以文件的一行为处理单位的 。awk每接收文件的一行,然后执行相应的命令,来处理文本 。
调用awk
2.shell脚本方式 3.将所有的awk命令插入一个单独文件,然后调用:
入门实例 复制代码 代码如下:[root@www ']# last -n 5 <==仅取出前五行 工作流程是这样的:读入有\n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域 。默认域分隔符是"空白键" 或 "[tab]键",所以$1表示登录用户,$3表示登录用户ip,以此类推 。
root pts/1 192.168.1.100 Tue Feb 10 11:21 still logged in root pts/1 192.168.1.100 Tue Feb 10 00:46 - 02:28 (01:41) root pts/1 192.168.1.100 Mon Feb 9 11:41 - 18:30 (06:48) dmtsai pts/1 192.168.1.100 Mon Feb 9 11:41 - 11:41 (00:00) root tty1 Fri Sep 5 14:09 - 14:10 (00:01)如果只是显示最近登录的5个帐号</p> <p>#last -n 5 | awk {print $1}rootrootrootdmtsairootawk
如果只是显示/etc/passwd的账户 复制代码 代码如下:#cat /etc/passwd |awk -F : {print $1} 这种是awk+action的示例,每行都会执行action{print $1} 。
root daemon bin sys -F指定域分隔符为: 。
如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割 复制代码 代码如下:#cat /etc/passwd |awk -F : {print $1"\t"$7}
root /bin/bash daemon /bin/sh bin /bin/sh sys /bin/sh 如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在所有行添加列名name,shell,在最后一行添加"blue,/bin/nosh" 。 复制代码 代码如下:cat /etc/passwd |awk -F : BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"} 工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action 。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作 。
name,shell root,/bin/bash daemon,/bin/sh bin,/bin/sh sys,/bin/sh .... blue,/bin/noshawk
搜索/etc/passwd有root关键字的所有行 复制代码 代码如下:#awk -F: /root/ /etc/passwd 这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容) 。
root:x:0:0:root:/root:/bin/bash 搜索支持正则,例如找root开头的: awk -F: /^root/ /etc/passwd
搜索/etc/passwd有root关键字的所有行,并显示对应的shell 复制代码 代码如下:# awk -F: /root/{print $7} /etc/passwd 这里指定了action{print $7}
/bin/bash
awk内置变量
统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容: 复制代码 代码如下:#awk -F : {print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0} /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh 使用printf替代print,可以让代码更加简洁,易读 复制代码 代码如下: awk -F : {printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)} /etc/passwd
print和printf 其中print函数的参数可以是变量、数值或者字符串 。字符串必须用双引号引用,参数用逗号分隔 。如果没有逗号,参数就串联在一起而无法区分 。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已 。 printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂 。 awk 日常常用学习笔记: # 取出两个文件中相同的部分 复制代码 代码如下:awk NR==FNR{a[$0]=0;next}{if($0 in a){print $0}} file1 file2
# 取出两个文件中不同的部分 复制代码 代码如下:awk NR==FNR{a[$0]=0;next}{if(!($0 in a)){print $0}} file1 file2
# 计算nginx日志访问排名前10位的ip 复制代码 代码如下:awk {a[$1]++}END{for(i in a) print a[i],i} access.log | sort -rn | head -10
#统计各个科目的数量 复制代码 代码如下:# cat test.txt
xqq 语文 数学 xq 英语 语文 x 数学 美术 awk {for(i=2;i<=NF;i++) a[$i]++}END{for(i in a) print i,a[i]} test.txt # 获取系统ip 复制代码 代码如下:ifconfig eth0 | awk NR==2{print $2} | cut -d: -f2 |