awk是Unix系统中文本处理工具,叫AWK是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符。
使用awk的方式有:
1.命令行方式awk [-F field-separator] ‘commands‘ input-file(s) 其中,commands 是真正awk命令,[-F 域分隔符]是可选的。 input-file(s) 是待处理的文件。在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。 command 命令需要在花括号中定义。 2.将所有的awk命令插入一个单独文件,然后调用: awk -f awk-script-file input-file(s) 其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。
以etc/passwd为例,说明awk使用。
~$ cat passwd.log
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash
sshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin
各个冒号分隔符含义:
login_name:passwd:UID:GID:user_name:home_dir:shell_path
1. 打印
[email protected]:~# awk -F ‘:‘ ‘{print $1, $4}‘ passwd.log root 0 daemon 1 bin 2 man 12 mail 8 nobody 65534 ym65536 1000 sshd 65534
- 其中单引号中的被大括号括着的就是awk的语句,注意,其只能被单引号包含。
- 其中的$1..$n表示第几例。注:$0表示整个行。
格式化输出和C类似
[email protected]:~# awk -F ‘:‘ ‘{printf "%-8s %-8s\n", $1, $4}‘ passwd.log root 0 daemon 1 bin 2 man 12 mail 8 nobody 65534 ym65536 1000 sshd 65534
2、过滤
a) 过滤条件:GID=65534且shell path = /bin/sh
[email protected]:~# awk -F: ‘$4==65534 && $7=="/bin/sh"‘ passwd.log nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
其中的“==”为比较运算符。其他比较运算符:!=, >, <, >=, <=
b) 显示GID>10的行
[email protected]:~# awk -F: ‘$4>10 {print $0}‘ passwd.log man:x:6:12:man:/var/cache/man:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/sh ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash sshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin
3、内建变量
awk的一些内建变量:
$0 | 当前记录(这个变量中存放着整个行的内容) |
$1~$n | 当前记录的第n个字段,字段间由FS分隔 |
FS | 输入字段分隔符 默认是空格或Tab |
NF | 当前记录中的字段个数,就是有多少列 |
NR | 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。 |
FNR | 当前记录数,与NR不同的是,这个值会是各个文件自己的行号 |
RS | 输入的记录分隔符, 默认为换行符 |
OFS | 输出字段分隔符, 默认也是空格 |
ORS | 输出的记录分隔符,默认为换行符 |
FILENAME | 当前输入文件的名字 |
打印行号大于6的行的信息:
[email protected]:~# awk -F ‘:‘ ‘NR > 6 {print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}‘ passwd.log filename:passwd.log,linenumber:7,columns:7,linecontent:ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash filename:passwd.log,linenumber:8,columns:7,linecontent:sshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin
4、BEGIN/END
[email protected]:~# awk -F: ‘BEGIN {print "longin UID"} {print $1,$3} END {print "END"}‘ passwd.log longin UID root 0 daemon 1 bin 2 man 6 mail 8 nobody 65534 ym65536 1000 sshd 114 END
awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。
5、字符串匹配
awk使用正则表达式进行匹配
a) 匹配第四列(GID)为65534的行,然后打印1,3列。
[email protected]:~# awk -F: ‘$4 ~ /65534/ {print $1,$3}‘ OFS=‘\t‘ passwd.log nobody 65534 sshd 114
//中的内容即为要匹配的内容。
b) 向grep一样匹配root字符串
[email protected]:~# awk -F: ‘/root/‘ passwd.log root:x:0:0:root:/root:/bin/bash
c) 匹配root或者ym
[email protected]:~# awk -F: ‘/root|ym/‘ passwd.log root:x:0:0:root:/root:/bin/bash ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash
6、if语句
awk中的if语句和C语言类似,使用如下:
if (expression) { statement1; } else if (expression1) { statement2; } else { statement3; }#注意每条语句以分号;结尾
把第一列匹配root或ym的行放入文件1.txt,其余的放入文件2.txt
awk -F: ‘{if($1 ~ /root|ym/) print > "1.txt"; else print > "2.txt"}‘ passwd.log [email protected]:~# ls 1.txt 2.txt passwd.log root:x:0:0:root:/root:/bin/bash ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash [email protected]:~# cat 2.txt daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/sh sshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin
7、统计
统计当前路径下txt文件大小的和:
[email protected]:~# ls -l *.txt -rw-r--r-- 1 root root 92 2015-02-23 23:11 1.txt -rw-r--r-- 1 root root 236 2015-02-23 23:11 2.txt [email protected]:~# ls -l *.txt |awk ‘BEGIN{sum=0} {sum += $5} END{print "txt file size is", sum}‘ txt file size is 328
统计GID=65534的行的个数:
[email protected]:~# awk -F: ‘BEGIN{count=0} {if($4==65534) count++} END{print count}‘ passwd.log 2