awk命令简介

来源:互联网 发布:linux下cat命令详解 编辑:程序博客网 时间:2024/05/22 07:54

简介

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

使用方法

awk ‘{pattern + action}’ {filenames}
其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。

举例子

  • 显示最近登录的5个帐号 last -n 5 | awk '{print $1}'
  • 显示/etc/passwd的账户 cat /etc/passwd |awk -F ':' '{print $1}'
  • 显示/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"}'

awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,0,1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。

  • 搜索/etc/passwd有root关键字的所有行,并显示对应的shell
    awk -F: '/root/{print $7}' /etc/passwd
    这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)

awk内置变量

这里写图片描述

  • 统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:
awk  -F ':'  '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd

awk编程

变量和赋值
下面统计/etc/passwd的账户人数

awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd

count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。
这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0:

awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd

统计某个文件夹下的文件占用的字节数

ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'

注意,统计不包括文件夹的子目录。

条件语句

统计某个文件夹下的文件占用的字节数,过滤4096大小的文件(一般都是文件夹):

ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}' 

数组
因为awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。

条件操作符
<、<=、==、!=、>=、~匹配正则表达式、!~不匹配正则表达式

  • 如果第四个域包含ASIMA,就打印整条
awk '{if ($4~/ASIMA/) print $0}' temp
  • 只打印第3域等于”48”的记录
awk '$3=="3" {print $0}' temp

第一个域小于第2个域

awk '{if ($1<$2) print $1 "is smaller"}' temp

设置大小写: awk ‘/[Gg]reen/’ temp

AND与关系: awk ‘{if ( 1=="a" &&2==”b” ) print $0}’ temp

awk ‘{if (1=="a"||1==”b”) print $0}’ temp

awk内置字符串函数

gsub(r,s) 在整个$0中用s替代r

awk 'gsub(/name/,"xingming") {print $0}' temp

index(s,t) 返回s中字符串t的第一位置

awk 'BEGIN {print index("Suny","ny")}' temp

多个文件合并操作。
这里写图片描述

与其他命令配合使用

如果work_dir下的某个模块文件数大于20个则删除

WORK_DIR=/usr/locol/testmod

find ${WORK_DIR}_bk  -maxdepth 1  -type d | grep -v "${WORK_DIR}_bk$" | xargs ls -ldt | awk -v service_name=$SERVICENAME '{if(NR>20 && $9 ~/'$service_name'/){print $9}}' | xargs rm -rf

该命令为找到当前目录上一级目录名称为testmod_bk
的文件夹。找到名称 为testmod_bk,按时间排序,如果记录大于 20,名册匹配则删除

第6 或7或8列匹配相应的名称则将相应的进程强制kill

ps ax | awk '($6 ~ "^'$BIN_DIR'") || ($7 ~ "^'$BIN_DIR'") || ($8 ~ "^'$BIN_DIR'") {print "kill -9 "$1;}' | /bin/sh 1>/dev/null 2>&1

将某个文件中的内容以固定的jason格式输出

源文件格式为
1 test.com abc.test.com
awk ’
BEGIN {FS=”\t”;}

    FILENAME=="'$TMP_DIR'/test.list"  {        printf "{";        printf "\"ID\":"$1", ";        printf "\"ZONE\":\""$2"\", ";        printf "\"DOMAIN\":"$3", ";        printf "\"CLASS\":\"IN\", ";        printf "\"TTL\":"600", ";        print "}";    }'  $TMP_DIR/test.list >$DATA_DIR/test.kxfr

输出后的文件
{“ID”:”1”,”ZONE”:”test.com”,”DOMAIN”:”abc.test.com”“,CLASS”:”IN”,“TTL”:600}

总结

awk功能强大。在文本处理方面比较优秀。能解决很多实际问题。另外AWK能与其他linux命令很好的配合使用。需要不断的练习才会熟练的使用。

0 0