文本三剑客之AWK

文本三剑客—-awk(3)

awk简介

awk是一个强大的文本分析工具,与grep(查找)、sed(编辑)一并称为“文本处理三剑客”。awk最强大的功能是对数据分析并生成报告。

awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk是AWK的GNU版本。

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。awk能读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

工作原理

一次读取一行文本,按输入分隔符进行切片,切成多个组成部分,将每片直接保存在内建的变量中,$1,$2,$3….,引用指定的变量,可以显示指定断,或者多个断。如果需要显示全部的,需要使用$0来引用。可以对单个片断进行判断,也可以对所有断进行循环判断。其默认分隔符为空格

  1. 按行读取文本(文件的每一行称为记录)
  2. 按输入分隔符进行切片
  3. 对切片自动生命变量 $1,$2…(域标识;$0为所有域)
  4. 对指定目标做处理(处理及打印等)

语法格式

awk [options] ‘program’ FILE……

[options]
–F:指明输入时的分隔符
–v:自定义变量
–f:调用awk脚本
program:pattern{action statements;..}
-pattern:触发条件
-action statements:对数据处理动作

步骤

  1. 执行BEGIN{action;…}
    BEGIN在输入之前执行,通常用来打印表头,变量初始化。
  2. 读取,执行pattern{action;…}
    默认执行{ print }
  3. 执行END{action;…}
    读取到打印结束后执行,通常用作分析结果,信息汇总。

变量

内置变量

  • FS:输入字段分隔符
  • OFS:输出字段分隔符
  • RS:输入记录分隔符
  • ORS:输出记录分隔符
  • ARGC:命令行参数的个数
  • ARGV:数组,保存命令行给定的各参数
  • NF:字段数量
  • NR:行号
  • FNR:个文件分别计数,行号
  • FILENAME:当前文件名

自定义变量

  1. 选项位置定义:-v var=hello
  2. 在program中定义:awk ‘BEGIN{test=”hello”;print test}’

字符串处理

  1. length([s]) :返回指定字符串的长度
  2. sub(r,s,[t]) :对t字符串进行搜索r 表示的模式匹配的内容,并将第一个匹配的内容替换为s
    echo “2008:08:08 08:08:08″ | awk ‘sub(/:/,”-“,$0)’
  3. gsub(r,s,[t]) :对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容
    echo “2008:08:08 08:08:08″ | awk ‘gsub(/:/,”-“,$0)’
  4. split(s,array,[r]) :以r为分隔符,切割字符串s,并将切割后的结果保存至array 所表示的数组中,第一个索引值为1, 第二个索引值为2,…
    netstat -tan | awk ‘/^tcp>/{split($5,ip,”:”);count[ip[1]]++} END{for (i in count) {print i,count[i]}}’

Printf命令

  1. print不需要指定,printf需要指定format
  2. printf后面的字串需要使用双引号
  3. 字串定义后的内容需要使用”,”分隔,后面直接跟Item1,item2….
  4. format用于指定后面的每个item的输出格式
  5. printf语句不会自动打印换行符\n

格式符

  1. %s: 显示字符串
  2. %d,%i: 显示十进制整数
  3. %e,%E: 科学计数法数值显示
  4. %f: 显示为浮点数
  5. %g,%G: 以科学数法或浮点形式显示数值
  6. %c: 显示字符的ASCII码
  7. %u: 无符号整数
  8. %%: 显示%号自身,相当于转义

修饰符

  1. N: 显示宽度
  2. -: 左对齐(默认为右对齐)
  3. +: 显示数值符号

操作符

  • 算数
    x+y, x-y, x*y, x/y, x^y, x%y
  • 赋值
    =, +=, -=, *=, /=, %=, ^=,++, —
  • 比较
    ==, !=, >, >=, <, <=
  • 模式匹配符
    ~:左边是否和右边匹配包含!~:是否不匹配
  • 逻辑
    &&,||,!

awk -F: ‘{printf “Username: %-15s,UID:%d\n”,$1,$3}’ /etc/passwd

PROGRAM

pattern

  1. )默认匹配每一行
  2. )/pattern/:仅处理匹配到的行
  3. )/pattern1/,/pattern2/:处理 pattern1 到 pattern2 之间
  4. )关系表达式:真:非0假:空或0

action

  1. )Expressions: 算术,比较表达式等
  2. ) Control statements :if, while等
  3. ) Compound statements :组合语句
  4. ) input statements
  5. ) output statements :print等

控制语句

  1. if-else
    awk ‘BEGIN{ test=100;if(test>90){print “very good”} else if(test>60){ print “good”}else{print “no pass”}}’
    成绩为100;大于90打印“very good”;大于60打印“good”;其余打印“no pass”
  2. while 循环
    条件”真”,进入循环;条件”假”,退出循环
    awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=10){print $i,length($i)}; i++}}’ /etc/grub2.cfg
    以空白符开头后跟”linux16″的行中,把字符数大于10的字符串打印出来。
  3. do-while 循环
    无论真假,至少执行一次
    awk ‘BEGIN{ sum=0;i=0;do{sum+=i;i++;}while(i<=100);print sum}’
    累加
  4. for 循环
    遍历
    awk ‘/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print$i,length($i)}}’ /etc/grub2.cfg
  5. switch 语句
  6. break 和 continue
    awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}’
    awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}’
  7. next
    提前 结束对本行处理而直接进入下一行处理
    seq {1,20} | awk -F: ‘{if($1%2==0)next ; print $1}’
    打印奇数行

数组

  1. )可使用任意字符串;字符串要使用双引号括起来
  2. )如果某数组元素事先不存在,在引用时,awk 会自动创建此元素,并将其值初始化为“空字符串(即为”假”)”
  • 若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历

示例练习:

[root@localhost ~]# awk -F: '$NF ~ /bash$/{print $1,$NF}' /etc/passwd
root /bin/bash
wang /bin/bash
lao /bin/bash
cai /bin/bash

 

[root@localhost ~]# awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
root /bin/bash
wang /bin/bash
lao /bin/bash
cai /bin/bash

 

[root@localhost ~]# cat f
aa
bb
cc
dd
aa
bb
cc
dd
[root@localhost ~]# awk '!arr[$0]++' f
aa
bb
cc
dd
[root@localhost ~]# awk '{!arr[$0]++;print $0,arr[$0]}' f
aa 1
bb 1
cc 1
dd 1
aa 2
bb 2
cc 2
dd 2

[root@localhost ~]# awk '/^UUID/||/^\/dev/{fs[$3]++} END{for (i in fs){print i,fs[i]}}' /etc/fstab
swap 1
xfs 4

 

[root@localhost ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count){print i,count[i]}}' /etc/fstab
man 1
and/or 1
maintained 1
xfs 4
Accessible 1
Thu 1
UUID=63af8e82-3a2a-40ed-8f76-64f56502ee1c 1are 1
defaults 4
blkid(8) 1
/ 1
/dev/mapper/cl-root 1
0 10

 

[root@localhost ~]# echo "Yd$C@M05MB%9&Bdh7dq+YVixp3vpw" | awk -F "[^[:digit:]]" '{for(k=1;k<=NF;k++){a[$k]}} END{for(i in a) {printf "%s",i}printf "\n"}'
79053

 

原创文章,作者:kstg5663294,如若转载,请注明出处:http://www.178linux.com/81635

赞 (6)
kstg5663294kstg5663294
上一篇 2017-07-17 17:19
下一篇 2017-07-17 19:34

相关推荐

  • 网卡别名与bonding配置

    我们知道,一般来说,一个硬件地址对应与一个IP地址。但在一些情况下,我们可以通过一些方法打破硬件地址与IP地址的一一对应关系。下面就来说一下网卡别名与bonding配置。 网卡别名就是将多个IP地址绑定到一个网络接口上,其命名方式为IFACE:num,如eth0:1等。需要注意的是,网卡别名仅对虚拟主机有效。创建网卡别名有两种方式: 1、ifconfig命令…

    Linux干货 2016-09-05
  • 函数式编程

    当我们说起函数式编程来说,我们会看到如下函数式编程的长相: 函数式编程的三大特性: immutable data 不可变数据:像Clojure一样,默认上变量是不可变的,如果你要改变变量,你需要把变量copy出去修改。这样一来,可以让你的程序少很多Bug。因为,程序中的状态不好维护,在并发的时候更不好维护。(你可以试想一下如果你的程序有个复杂的状态,当以后别…

    Linux干货 2016-08-15
  • 08.04 笔记总结

    1.ps axo  user,ruser,group,rgroup,cmd  //  ruser  表示程序发起的用户,一般是指系统当前的用户  //  user  表示程序的所有者。在大数情况下,两个用户都是系统当前的用户, 之后当程序被赋予suid的时候,可能user会发生变化。 2.…

    Linux干货 2016-08-08
  • 探索处理文本工具“sed”的相关奥妙

    一:sed工具 1,set的介绍:sed是一种流编辑器,它一次处理一行内容。处理时,把当前 处理的行存储在临时缓冲区中,称为“模式空间”(patternspace),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断…

    2017-08-26
  • N27—第十周作业

    N27_第十周作业 1、请详细描述Centos系统的启动流程(详细到每个过程系统做了哪些事情) 详情请参考http://www.178linux.com/85713 2、为运行于虚拟机上的Centos 6添加一块新的硬盘,提供两个主分区; (1)为硬盘新建两个主分区;并为其安装grub (2)为硬盘的第一个主分区提供内核和ramdisk文件;为第二个分区提供…

    Linux干货 2017-10-21
  • 文件权限

    普通文件 r: 可以读取文件的内容 w: 可以修改文件的内容 x: 可以执行该文件 执行脚本(不要随便给文件加x权限) 目录文件 r: 用户可以列出目录下有哪些文件(不能查看文件的详细信息) w: 只有w无意义。 x: 用户可以进入该目录(如果知道文件名,且有相对应的文件权限 ,可以执行对应的操作) 权限一般配合使用,不同权限配合有不同效果 rx: 用户可以…

    2017-07-30