20 October 2014

awk命令

是一种编程语言,用于linux/unix下的文本和数据处理,数据来源于标准输入,一个或多个文件,其他命令的输出。

处理流程:逐行扫描文件,从第一行到最后一行,寻找匹配的行,并在该行做你想做的事;如果没有指定action,则直接输出;如果没有指定pattern,则所有行被处理。

使用语法

awk '{pattern action}' input-file(s)}

使用方式

1.命令方式
	awk [-F fs] 'commands' input-file(s)
2.脚本方式
	#!/bin/awk
3.文件方式
	awk -f awk-script-file input-file

小试牛刀

/etc/passwd的数据内容格式
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
_uucp:*:4:4:Unix to Unix Copy Protocol:/var/spool/uucp:/usr/sbin/uucico
_taskgated:*:13:13:Task Gate Daemon:/var/empty:/usr/bin/false
_networkd:*:24:24:Network Services:/var/networkd:/usr/bin/false
_installassistant:*:25:25:Install Assistant:/var/empty:/usr/bin/false

1.统计所有的账号列表($0,$1....的意思)
	awk -F ':'  '{print $1}' /etc/passwd
	
2.统计账号的个数(内置变量)
	awk -F ':' '{count++;} END{print "user account size is ",count}' /etc/passwd	
	
3.去重后的账号列表
	awk -F ':' ''
		
4.统计/etc/passwd文件名,行号(printf使用)
	 awk  -F ':'  '{printf("filename:%s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
	
5.输出账号的序号(数组,for循环的使用)
	awk -F ':' 'BEGIN{count = 0;} {account[count]=$1;count++;} END{for(i=0 ;i<count;i++) print i, account[i]}' /etc/passwd

6.统计某个文件夹下文件大于1M
	ls -l |awk '{if ($5 > 1024*1024) {print $9" "$5/1024/1024, "M"}}' 
	ls -l /home/admin/work |awk '{if ($5 > 1024*1024) {print $9" "$5/1024/1024, "M"}}' 

内置变量

$0 当前行
$1...$n	当前记录的第N个字段,字段间由FS分隔
ARGC	命令行参数个数
AGRV	命令行参数排序
EVRIRON	
FILENAME	awk浏览的文件名
FNR	当前记录数,各个文件自己的行号
FS	输入域分隔符,默认空格或tab
NF	当前记录中的字段个数,也就是列数
NR	已读出的记录数,就是行号,从1开始,如果有多个文件,不断累加
OFS	输出的字段分隔符,默认空格
ORS	输出记录分隔符,默认换行 awk -F ":" ' END {print ORS}' /etc/passwd
RS	输入的记录分隔符,默认换行 awk -F ":" ' END {print RS}' /etc/passwd
NF	浏览记录的域个数 awk -F ":" ' END {print NF}' /etc/passwd

过滤记录

<	awk -F ":" '{if($3 < 1) print $1}' /etc/passwd
<=	awk -F ":" '{if($3 <= 1) print $1}' /etc/passwd
>	awk -F ":" '{if($3 > 1) print $1}' /etc/passwd
>=	awk -F ":" '{if($3 >= 1) print $1}' /etc/passwd
!=	awk -F ":" '{if($3 != 1) print $1}' /etc/passwd
==	awk -F ":" '{if($3 == 1) print $1}' /etc/passwd
~	awk -F ":" '{if($1~/root/) print $1}' /etc/passwd
!~	awk -F ":" '{if($1!~/root/) print $1}' /etc/passwd
&&	awk -F ":" '{if($3 > 2 && $3 != 4) print $1 , $3}' /etc/passwd
||	awk -F ":" '{if($3 > 2 || $3 == 4) print $1 , $3}' /etc/passwd

字符串匹配

匹配/etc/passwd中第1列是root的行及内容

awk -F ":"  '$1 ~ /root/ {print NR, $0}' /etc/passed
12 root:*:0:0:System Administrator:/var/root:/bin/sh
62 _cvmsroot:*:212:212:CVMS Root:/var/empty:/usr/bin/false

匹配/etc/passwd行中包含root的行及内容

awk '/root/ {print NR,$0}' /etc/passwd
12 root:*:0:0:System Administrator:/var/root:/bin/sh
13 daemon:*:1:1:System Services:/var/root:/usr/bin/false
62 _cvmsroot:*:212:212:CVMS Root:/var/empty:/usr/bin/false

拆分文件

相同的列归类到一个文件中

ps aux | awk 'NR !=1{print > $1}'
17926830 -rw-r--r--   1 jimmy  staff    128 11  4 23:37 _appleevents
17926826 -rw-r--r--   1 jimmy  staff     98 11  4 23:37 _coreaudiod
17926831 -rw-r--r--   1 jimmy  staff    100 11  4 23:37 _locationd
17926834 -rw-r--r--   1 jimmy  staff    101 11  4 23:37 _mdnsresponder
17926828 -rw-r--r--   1 jimmy  staff    100 11  4 23:37 _netbios
17926833 -rw-r--r--   1 jimmy  staff     99 11  4 23:37 _networkd
17926829 -rw-r--r--   1 jimmy  staff    446 11  4 23:37 _spotlight
17926832 -rw-r--r--   1 jimmy  staff    172 11  4 23:37 _usbmuxd
17926825 -rw-r--r--   1 jimmy  staff    199 11  4 23:37 _windowserver
17926824 -rw-r--r--   1 jimmy  staff  49272 11  4 23:37 jimmy
17926827 -rw-r--r--   1 jimmy  staff   7158 11  4 23:37 root

将过滤的内容输出到指定的文件中

ps aux | awk 'NR !=1{print $1 > "a.txt"}'
jimmy
jimmy
jimmy
jimmy
jimmy
jimmy

统计

遍历每个文件的行数

for i in `ll |awk '{print $10}'` ; do wc -l $i ; done  > file-line-count.txt

统计总文件大小

awk -F "mailSize" '{print $2}' * | awk -F "\"" '{print $3}' | awk -F "\\" '{sum+=$1} END {print sum/1024/1024/1024}'

统计每个文件的大小

for i in `ll |awk '{print $10}'` ;  do echo $i; awk -F "mailSize" '{print $2}' $i | awk -F "\"" '{print $3}' | awk -F "\\" '{sum+=$1} END {print FILENAME, sum/1024/1024}' ; done > size.txt

统计文件超过10M,20M的个数

awk -F "mailSize" '{print $2}' * | awk -F "\"" '{print $3}' | awk -F "\\" '{sum+=$1} END {print sum/1024/1024/1024}'

awk -F "mailSize" '{print $2}' * |awk -F "\"" '{print $3}' |awk -F "\\" '{if($1 > 20971520) sum+=1} END {print sum}'

按文件大小进行排序

ls -lR | awk '{if($5 > 0) print $5/1024/1024,"M",$9}' |sort  -nr

环境变量

使用脚本



blog comments powered by Disqus