你不得不会的awk

1、概述

  • grep 文本过滤工具,逐行扫扫描匹配显示
  • sed 只处理模式空间不处理源空间
  • awk 只读入的文本进行切片、处理

2、awk的使用

awk [options] 'script' file1,file2,...
awk [options] 'PATTERN { action }' file1,file2,...
$0 引用被引用的整行
$1 引用第一片
...
# awk '{print $1}' 1.txt    # 显示第一个字段,默认以空格分隔
# df -h | awk '{print $1}'  # 显示第一个字段,默认以换行符分隔

2.1、常用符

-F :字段分隔符
# awk -F: '{print $1 $7}' /etc/passwd
NF : number of fields  当前记录字段的个数
# awk -F: '{print $1 $NF}' /etc/passwd
FS :field separator 默认是空白字符
RS :record separator 默认是换行符
# awk -v FS=: '{print $1 $NF}' /etc/passwd
OFS :output field separator 输出字段分隔符
# awk -v OFS=: '{print $1,$2}' 1.txt

2.2、printf

命令格式

printf format ,item1,item2 ...

1、与print 最大的不同是,printf需要指定format;
2、format用于指定后面的每个item的输出格式;
3、printf语句不会自动打印换行符:\n

2.3、format格式

format格式的指示符以%开头,后跟字符:

%c:显示字符的ASCII码
%d,%i: 十进制整数
%e,%E: 科学计数法显示数值
%f: 显示符点数
%g,%G: 以科学计数法的格式或浮点数的模式显示数值
%s: 显示字符串
%u:无符号整数
%%: 显示%本身
# awk '{printf "%-10s%s\n",$1,$2}' 1.txt 
welcome   to
how       are
bye,sir.  

2.4、修饰符:

N:显示宽度
-:左对齐
+:显示数字符号

2.5、输出重定向

print items > output-file
print items >> output-file	
print items | command

特殊文件描述:

/dev/stdin:标准输入
/dev/stdout:标准输出
/dev/stderr:错误输出
/dev/fd/N:某特定文件描述符,如/dev/stdin 相当于/dev/fd/0
# awk -F: '{printf "%-15s%i\n",$1,$3}' /etc/passwd
# awk -F: '{printf "%-15s%i\n",$1,$3 > "/dev/stderr"}' /etc/passwd

3、awk 的操作符

3.1、算术操作符

-x:负值
+x:转换为整数
x^y,x**y:次方
x*y:相乘
x/y:除
x+Y
x-y
x%y

3.2、字符串操作符

只有一个不用写出来,用于实现字符连接

# awk 'BEGIN{print "a" "b"}'

3.3、赋值操作符

=
+=
-=
*=
/=
%=
^=
**=
==
--
# 注:如果模式为=,此时用/=/可能会用语法错误,用/[=]/

3.4、布尔值

在awk中,任何非零值或非空字符串都为真,反之就为假

3.5、比较操作符

x < y 
x <= y
x > y
x >= y
x == y
x != y
x ~ y
X !~ y  
~ :表示匹配模式

# awk -F: '$1 ~ /root/ {print $3,$4,$NF}' /etc/passwd
# awk -F: '$1 !~ /root/ {print $3,$4,$NF}' /etc/passwd

3.6、表达式间的逻辑关系符

&&  逻辑与
||	逻辑或

3.7、条件表达式

selector?if-true-exp:if-false-exp

3.8、函数调用

functon_name (para1,para2)

4、awk 模式

awk 'program' input-file1 input-file2
'program ' 为
pattern { action }
pattern { action }
...

常见的模式类型:

4.1、regexp

正则表达式,模式为/regular expresson/
# awk -F: '/bash/ {print $0}' /etc/passwd
# awk -F: '/bash/ {print $1}' /etc/passwd

4.2、expresssion

表达式,其值非0或为非空字符时满足条件
如:$1 ~ /luke/ 或$1 == "1"  ,运用匹配符
# awk -F: '$3 >= 500 {print $1,$3,$NF}' /etc/passwd

4.3、ranges

指定匹配范围pattern1,pattern2

4.4、BEGIN/END

特殊模式,仅在awk命令执行前运行一次或结束前运行一次
# awk -F: 'BEGIN{print"user      id"}$3>=500{printf "%-10s%s\n",$1,$3}' /etc/passwd
# awk -F: 'BEGIN{print"user      id"}$3>=500{printf "%-10s%s\n",$1,$3}END{print"over"}' /etc/passwd
# awk 'BEGIN{print"a""b"}'
# awk 'BEGIN{FS=":"}{print $1,$3}' /etc/passwd     # BEGIN字段中赋值

4.5、empty

空模式,匹配何意字符

5、action 控制语句

5.1、if-else

语法:if (condition) {then-body} else {[ else-body ]}
# awk -F: '{if ($3==0) print $1,"admin";else print $1,"common user"}' /etc/passwd
# awk -F: '{if($3==0) printf "%-10s:%s\n",$1,"admin";else printf "%-10s:%s\n",$1,"common user"}' /etc/passwd
# awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd			#赋值条件
组合例子
# awk -F: 'BEGIN{print "user       id"}{if($3>=500)printf "%-10s%s\n",$1,$3}END{print "over....."}' /etc/passwd
# awk -F: 'BEGIN{print "user      id"}{if($3==0)printf "%-10s%-5s%s\n",$1,$3,"admin";else printf "%-10s%-5s%s\n",$1,$3,"others"}END{print "over....."}' /etc/passwd

5.2、while

语法:while (condition){statement1;statement2;...}  将每一行切片后分别做处理,先满足条件,然后循环执行
# awk -F: '$1!~/root/{a=1;while (a<=NF) {print $a;a+=2}}' /etc/passwd	# ,;两次结果不同
# awk -F: '$1!~/root/{a=1;while (a<=NF) {print $a,a+=2}}' /etc/passwd
注:print 输出换行,printf输出不换行

5.3、do-while

语法:do {statement1,statement2,...}while(condition)    先执行一遍动作再匹配条件
# awk -F: '$1!~/root/{a=1;do{print $a,a++}while(a<=NF)}' /etc/passwd

5.4、for

语法:for (varialbe assignment;condition;iteration process) {statement1,statement2,...}
# awk -F: '{for(a=1;a<=NF;a++) print $a}' /etc/passwd

5.5、case

5.6、break & continue

5.7、next

6、awk中的数组

A[b]

# awk 'BEGIN{A["x"]="nihao";A["y"]="buhao";print A["x"],A["y"]}'
# awk 'BEGIN{a="nihao";b="buhao";print a,b}'

# netstat -ant | awk '$1~/tcp/{S[$NF]++}END{for(A in S) print A ,S[A]}'

# awk -F: '$NF!~/^$/{S[$NF]++}END{for(A in S) printf "%s:%s\n",A,S[A]}' /etc/passwd 

7、awk中函数

7.1、split

# netstat -ant | awk '/:50931/{split($5,B,":");IP[B[1]]++}END{for (i in IP){print IP[i],i}}' | sort -rn | head -50

8、awk 实例

求和
# awk '{sum+=$1}END{print sum}' 3.txt
	
求平均值
# awk '{sum+=$1}END{print sum/$NF}' 3.txt
	
求平和与平均值
# awk '{sum+=$1}END{print "sum =",sum,", ""everage =",sum/NR}' 4.sh
sum = 9725 , everage = 1620.83

求最大值
# awk 'BEGIN{max=0}{if($1>max)max=$1}END{print max}' 3.txt

求最小值
# awk 'BEGIN{min=19999999}{if($1<min)min=$1}END{print min}' 3.txt

访问的top10
# cat output/logs/cookie_logs/`date +%u`/cookie_log|grep -v '172.16'|grep -v '127.0.0.1' |awk -F' '  '{ if(index($1,"219.141.246")!=0) print $2; else print $1  } '|sort|uniq -c|sort -n |tail -n 10
posted @ 2016-01-28 14:44  YaYaTang  阅读(190)  评论(0编辑  收藏  举报