AWK

作者: 花泽菠菜xqc | 来源:发表于2019-04-23 10:59 被阅读0次

AWK

awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个
或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix
下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。
awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定
模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(
屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。awk分别代表其作者姓氏的第一个字
母。因为它的作者是三个人,分别是Alfred Aho、Brian Kernighan、Peter Weinberger。gawk是awk的
GNU版本,它提供了Bell实验室和GNU的一些扩展。

$ cat gy.txt
机构号  机构名称        省别    尾箱号  尾箱状态   领用柜员号   领用柜员姓名    币种    余额
11007eee        北京东城区街支行  北京    03      未领用                  156     19001.68
11007eee        北京东城区街支行  北京    03      未领用                  840     2672.00
11007eee        北京东城区街支行  北京    04      未领用                  156     7261.31
11007eee        北京朝阳区路支行  北京    02      未领用                  156     161490.08
11007eee        北京朝阳区路支行  北京    03      未领用                  840     19711.00
11007eee        北京朝阳区路支行  北京    03      未领用                  156     282370.23
11007eee        北京朝阳区路支行  北京    04      未领用                  840     24551.00
11007eee        北京朝阳区路支行  北京    04      未领用                  156     372689.36
11007eee        北京朝阳区行      北京    02      未领用                  156     304516.23

$ awk '{printf "%-8s %-8s %-8s\n",$1,$2,$3}' 

过滤记录
过滤条件为:第 3 列的值为山东 && 第 5 列的值为 未领用)

$ awk '$3=="山东" && $5=="未领用" ' gy.txt

其中的 == 为比较运算符。其他比较运算符:!=, >, <, >=, <=

各种过滤记录的方式:

$ awk ' $4 > 3 {print $0}' gy.txt

如果我们需要表头的话,我们可以引入内建变量NR:

$ awk '$3=="山东" && $5=="未领用"  || NR==1 ' gy.txt

再加上格式化输出:

$ awk '$3=="山东" && $5=="未领用" || NR==1 {printf "%-10s %-21s %-6s\n",$1,$2,$3}' gy.txt

内建变量

awk的一些内建变量:

[图片上传失败...(image-5a7589-1555988349538)]

$n 当前记录的第n个字段,字段间由FS分隔
FS 输入字段分隔符 默认是空格或Tab
NF 当前记录中的字段个数,就是有多少列

$NF 最后一列

NR 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
FNR 当前记录数,与NR不同的是,这个值会是各个文件自己的行号
RS 输入的记录分隔符, 默认为换行符
OFS 输出字段分隔符, 默认也是空格
ORS 输出的记录分隔符,默认为换行符
FILENAME 当前输入文件的名字

怎么使用呢,比如:我们如果要输出行号:

$ awk '$3=="山东" && $5=="未领用" || NR==1 {printf "%-6s %-5s %-12s %-15s %-2s \n",NR, FNR, $1,$2,$3}' gy.txt

指定分隔符

$  awk  'BEGIN{FS=":"} {print $1,$3,$6}' /etc/passwd

上面的命令也等价于:
-F的意思就是指定分隔符

$ awk  -F: '{print $1,$3,$6}' /etc/passwd

指定多个分隔符:

awk -F '[;:]'

再来看一个以\t作为分隔符输出的例子(下面使用了/etc/passwd文件,这个文件是以:分隔的):

$ awk  -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd
root    0       /root
bin     1       /bin
daemon  2       /sbin
adm     3       /var/adm
lp      4       /var/spool/lpd
sync    5       /sbin

字符串匹配

示例:

awk '$2 ~ /平阴县/ || NR==1 {print NR, $1,$4}' gy.txt

~ 表示模式开始。
/ / 中是模式。这就是一个正则表达式的匹配。

其实awk可以像grep一样的去匹配第一行,就像这样:

$ awk '/.*县/' gy.txt

我们可以使用 “/平阴县|济阳县/” 来匹配 平阴县 或者 济阳县 :

$ awk '$2 ~ /平阴县|济阳县/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" gy.txt

再来看看模式取反的例子:

$ awk '$2 !~ /平阴县/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" gy.txt

或是:

$ awk '!/平阴县/' gy.txt

折分文件

awk拆分文件很简单,使用重定向就好了。

下面这个例子,是按第 3 例分隔文件,相当的简单(其中的NR!=1表示不处理表头)。

$ awk 'NR!=1{print > $3}' gy.txt
$ ls
gy.txt  北京     山东     山西     江苏 

你也可以把指定的列输出到文件:

awk 'NR!=1{print $2,$4,$5 > $3}' gy.txt

再复杂一点:(注意其中的if-else-if语句,可见awk其实是个脚本解释器)

$ awk 'NR!=1 {if($3 ~ /北京|山东/) print > "1.txt";
else if($3 ~ /山西/) print > "2.txt";
else print > "3.txt" }' gy.txt

$ ls ?.txt
1.txt  2.txt  3.txt

统计

下面的命令计算所有的 txt 文件的文件大小总和。

$ ls -l  *.txt | awk '{sum+=$5} END {print sum}'
2511401

我们再来看一个统计各个各省份网点数量的用法:

$ awk 'NR!=1 {a[$3]++;} END {for (i in a) print i ", " a[i];}' gy.txt
北京, 69
山西, 20
江苏, 10
山东, 16

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

$ ps aux | awk 'NR!=1 {a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'

awk脚本

BEGINEND,这两个关键字意味着执行前和执行后的意思,语法如下:

BEGIN { 这里面放的是执行前的语句 }

END {这里面放的是处理完所有的行后要执行的语句 }

{这里面放的是处理每一行时要执行的语句}

示例:

假设有这么一个文件(学生成绩表):

$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

我们的awk脚本如下:

$ cat cal.awk
#!/bin/awk -f
#处理每行之前
BEGIN {
    math = 0
    english = 0
    computer = 0

    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}

#处理中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}

#处理后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}

我们来看一下执行结果:(也可以这样运行 ./cal.awk score.txt)

$ awk -f cal.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  TOTAL:       319      393      350
AVERAGE:     63.80    78.60    70.00

环境变量

怎么和环境变量交互:(使用-v参数和ENVIRON,使用ENVIRON的环境变量需要export)

$ x=5
$ y=10
$ export y

$ echo $x $y
5 10

$ awk -v val=$x '{print $1, $2, $3, $4+val, $5+ENVIRON["y"]}' OFS="\t" score.txt
Marry   2143    78      89      87
Jack    2321    66      83      55
Tom     2122    48      82      81
Mike    2537    87      102     105
Bob     2415    40      62      72

最后,我们再来看几个小例子:

#从file文件中找出长度大于80的行
awk 'length>80' file

#按连接数查看客户端IP
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr

#打印99乘法表
seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'

关于其中的一些知识点可以参看gawk的手册:

内建变量,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din-Variables

流控方面,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Statements

内建函数,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din

正则表达式,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Regexp

相关文章

  • 18-文本处理三剑客之awk

    本章内容 ◆ awk介绍◆ awk基本用法◆ awk变量◆ awk格式化◆ awk操作符◆ awk条件判断◆ aw...

  • 2017 09-04 AWK

    本章主要学习内容awk介绍 awk基本用法 awk变量 awk格式化 awk操作符 awk条件判断 a...

  • 【技术案例】跟老男孩学运维-awk项目案例

    一个awk数组应用案例 [TOC] 0.技术点: awk awk数组 awk判断 awk数组赋值 awk函数spl...

  • awk

    awk:报告生成器,格式化文本输出 内容: awk介绍 awk基本用法 awk变量 awk格式化 awk操作符 a...

  • awk

    Linux System Environment awk功能 awk格式 awk 参数 一、awk截取列 二、显示...

  • 笔记-awk

    1.Awk基础介绍 2.awk语法格式 2.Awk工作原理 3.Awk内部变量 4.Awk格式输出 5.Awk模式...

  • awk用法详解

    awk 用法 awk ' pattern {action} ' 1、awk '/101/' file ...

  • Day64-shell编程_正则表达式_awk

    1.Awk基础介绍 2.Awk工作原理 3.Awk内部变量 4.Awk格式输出 5.Awk模式匹配 5.1符号 ...

  • linux-awk

    linux-awk awk基本结构 awk ‘BEGIN{ print “start”} pattern { co...

  • awk小说

    awk awk脚本的结构基本如下: awk ' BEGIN{ print "start" } patern { c...

网友评论

      本文标题:AWK

      本文链接:https://www.haomeiwen.com/subject/psnmgqtx.html