首页 > 代码库 > awk
awk
awk知识
基础理论
awk语句都有模式和动做组成。在一个awk脚本中可能有许多语句。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。如果省略模式部分,动作将时刻保持执行状态。
1.模式可以是任何的条件语句或是复合语句或是正则表达式。模式包括两个字段 BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文件开始执行。
如果不特别指明模式。awk总是匹配或打印行数。
实际动作在{}内指明。
常看awk版本
[root@localhost pangbing]# awk -W version
GNU Awk 3.1.7
Copyright (C) 1989, 1991-2009 Free Software Foundation.
2.域和记录
域的标记为$1 $2 $3.....。这种方法称为域标识。
$0表示所有域。例子:awk ‘{print $0}‘ 文件名
例子:awk ‘{print $0}‘ 文件名 > 文件名 | tee 文件名
管道前边的结果会直接输出到文件,不会输出到屏幕上。tee命令就是能同时让结果输出到屏幕上。
打印不同的域,中间用逗号隔开。
例子:‘{print$1,$3,$7}‘
3.awk 匹配正则表达式
元字符:
这里是 a w k中正则表达式匹配操作中经常用到的字符:
\ ^ $ . [] [^] | () * +
?
条件操作符
表9 - 2给出a w k条件操作符,后面将给出其用法。
表9-2 awk条件操作符
操 作 符 描 述
操 作 符
描 述
<
小于
>=
大于等于
<=
小于等于
~ 匹配正则表达式
==
等于
!~ 不匹配正则表达式
!=
不等于
<1> 匹配
为使某一域号匹配正则表达式,使用符号‘~’后紧跟正则表达式
例子:
awk /root/ /etc/passwd 这个是简单的写法 ;passwd文件中只要含有root的行就打印出来
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
awk -F: ‘$1~/root/‘ /etc/passwd 意思是以:
为分隔符号,打印第一段(区域)匹配含有root的行
root:x:0:0:root:/root:/bin/bash
awk -F: ‘$3~/0/‘ /etc/passwd 意思是以:为分隔符号,打印第三段(区域)匹配含有0的行
awk -F: ‘$3=="0"‘ /etc/passwd 意思是以:为分隔符号,打印第三段(区域)匹配是0的行(这时精确匹配)
awk ‘/^ /‘ 文件名 匹配以空格开头的行
awk ‘/^ | ^#/‘ httpd.conf 匹配空格开头的或者是^#开头的
awk ‘!(/表达式1/&& /表达式2/)‘ /etc/passwd
表示取反
<2>. 精确匹配
为精确匹配 48,使用等号 ==,并用单引号括起条件。例如 $3==“48” ,这样确保只有 4 8序号得以匹配,其余则不行。
awk -F: ‘$3~/0/‘ /etc/passwd 意思是以:为分隔符号,打印第三段(区域)匹配含有0的行
root:x:0:0:root:/root:/bin/bash
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
pangbing:x:500:500:pangbing:/home/pangbing:/bin/bash
awk -F: ‘$3=="0"‘ /etc/passwd 意思是以:为分隔符号,打印第三段(区域)匹配只是0的行(这是精确匹配)
################
root:x:0:0:root:/root:/bin/bash
<3> 不匹配
awk -F: ‘$3!="0"‘ /etc/passwd
awk -F: ‘$3!~/0/‘ /etc/passwd
<4>比较
awk -F: ‘$3>=$4‘ /etc/passwd
4.计算
[root@localhost pangbing]# cat 1
1 11
2 12
3 14
4 22
<1>求和
格式: awk ‘{变量名+=第几列}END{print 变量名}‘ 文件名
[root@localhost pangbing]#
awk ‘{sum+=$1}END{print sum}‘ 1
10
[root@localhost pangbing]#
awk ‘{sum+=$2}END{print sum}‘ 1
59
<2>求平均值
格式:awk ‘{变量名+=第几列}END{print 变量名/NR}‘ 文件名
[root@localhost pangbing]# awk ‘{a+=$2}END{print a/NR}‘ 1
14.75
5.多条件同时匹配
[root@localhost pangbing]# cat 1
1 11
1 12 asd fff
1 13 2
同时匹配多个条件
格式:awk ‘条件1 && 条件2 && 条件...‘ 文件名
[root@localhost pangbing]#
awk ‘$1~/1/ && $2~/12/‘ 1
awk ‘$1~"1" && $2~"12"‘ 1 //也可以用""代替
1 12 asd fff
<1>前提是用 ~ 匹配时可以用双引号替换//,
<2>/表达式/单独出现时,不要用双引号替换,结果会有误。
6.awk中的for循环
[root@localhost pangbing]# cat b
pppppp
例子:[root@localhost pangbing]# awk ‘{for (i=1;i<=10;i++) print i}‘ b
1
2
3
4
其中
for(i=1;i<=10;i++)循环的意思是:定义了一个取值列表
for (变量=开始;停止循环的条件;步进长度)
停止循环的条件:是指满足条件就循环,不满足就停止循环。
误区:我这个循环理错了:
i做一次赋值运算,然后用i<=10这个条件判断i的值是不是小于10,然后做i的值做+1运算,然后i在从新赋值等于1,判断,运算。然后i在从新赋值等于1,判断,运算。我是这样错误理解这个循环的。这样i不是永远都 等于2了。
正确理解:这里边真正的循环体是i=1,
i<=10和i++:是给i=1循环时候添加的附加条件
i++:定义了 i 循环时候的运算方式。是说你每次循环都加1,
i<=10 :那么加到什么时候为止呢,i不在小于等于10的时候就停止循环。
循环过程:i=1 判断是否满足条件,满足就1+1
这时i=2了。还满足条件 在2+1
这时i=3了.还满足条件 在3+1
一直循环到不满足条件为止。
<2>另一种for的写法
这种写法和shell一样
for(i in 取值列表)
4. awk内置变量
a w k有许多内置变量用来设置环境信息。这些变量可以被改变。表 9 - 3显示了最常使用的
一些变量,并给出其基本含义
A R G C 命令行参数个数
A R G V 命令行参数排列
E N V I R O N 支持队列中系统环境变量的使用
FILENAME a w k浏览的文件名
F N R 浏览文件的记录数
F S 设置输入域分隔符,等价于命令行 - F选项
N F 浏览记录的域个数($NF表示最后一段。)
N R 已读的记录数
O F S 输出域分隔符
O R S 输出记录分隔符
R S 控制记录分隔符
5.ifconfig eth0 | awk -F[" ":]+ ‘/inet addr/ {print $4}‘
这是快速过滤出IP地址的方法
awk BEGIN EDN
awk ‘BEGIN{print "+++++++++"}{print $2}END{print ________}‘
echo 1234567890|awk -F "^C‘{print $5}‘
5
awk ‘{print $1,$NF,$(NF-1),$RS,$(NR-1),$(NR+1)}‘
cat a.log |awk ‘{print $1}‘|sort|uniq -c|sort -nr
统计ip次数
awk ‘{print $1}‘ a.log |sort|uniq -c|sort -nr
优化后
awk ‘{a[$1]++}END{for (i in a)print a[i],i}‘|sort -nr
*
a[$i]++
创建一个哈希数组,数组的key是每一列的内容a1、b1、a1、c1......,数组的value是每一列出现的次数
awk 哈希数组
awk printf 制表符
过滤ip地址
grep -o ‘\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}‘ urfile
awk