awk的基本格式
awk [options] ‘program’ filename

可执行脚本代码在中括号里,再由单引号括起来
awk每读取一行内容,会执行一次脚本代码,根据脚本代码里的条件来判断是否要执行后面的操作。也就是说以行为一次处理单位
$1/$2/$3…/$n分别代表当前行的第一列/第二列/第三列内容…/第n列字段
$0 表示当前行,即一整行数据
NR 当前awk所处理的是第几行,表示当前行号
NF 每行的总列数,字段总数
FS 输入分割字符
OFS 输出分割字符

演示文本awk.txt

The Zen of Python, by Tim Peters
Beautiful is better than ugly.thanExplicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
A B C D E F1 2 3 4 5 6

awk '{print $0}' awk.txt   显示所有内容


-F 指定分隔符,默认是空格或[TAB],也可以同时指定多个分隔符比如 ‘[][]’,就是以[和]来作为分隔符

awk -F 'is' '{print $1}' awk.txt   以is来作为分隔符
The Zen of Python, by Tim Peters
Beautiful 
Explicit 
Simple 
Complex Flat Sparse 
A B C D E F1 2 3 4 5 6


赋值(变量)

awk -v abc=123 -F ":" '{print $1,abc}' awk.txt

awk '{$2="hello";print $0}' awk.txt  把第二列的内容替换为hello然后显示。原来的内容不变
The hello of Python, by Tim Peters
Beautiful hello better than ugly.than
Explicit hello better than implicit.
Simple hello better than complex.Complex hello better than complicated.Flat hello better than nested.
Sparse hello better than dense.
A hello C D E F1 hello 3 4 5 6


给变量abc赋值在输出,此时与awk.txt文件的内容显示无关。此时会显示九行hello world,因为awk是针对目标文件的每一行来做一次处理,有多少行就执行多少次

awk '{abc="hello world";print abc}' awk.txt
awk 'BEGIN{abc="hello world"}{print abc}' awk.txt   效果一样


NR指目前awk处理的当前行数

awk '{print NR,$0}' awk.txt    显示行号1 The Zen of Python, by Tim Peters2 Beautiful is better than ugly.than3 Explicit is better than implicit.4 Simple is better than complex.5 Complex is better than complicated.6 Flat is better than nested.7 Sparse is better than dense.8 A B C D E F9 1 2 3 4 5 6


NF指每一行的列数

awk '{print NF,$1}' awk.txt    显示每行列数7 The5 Beautiful5 Explicit5 Simple5 Complex5 Flat5 Sparse6 A6 1


$NF即指最后一列数据

$NFawk '{print $NF}' awk.txt  显示最后一列内容
awk '{print $(NF-1)}' awk.txt  倒数第二列内容,依次递减显示对应列
Tim
than
than
than
than
than
than
E5


awk '{print $1,$2,$3}' awk.txt    输出三列内容,其中**逗号**指插入输出分隔符,就是默认的空格,可以修改awk '{ print $1 "\t" $2 "\t" $3}' awk.txt  修改的时候要加上双引号The Zen ofBeautiful   is  betterExplicit    is  better
Simple  is  better
Complex is  better
Flat    is  better
Sparse  is  better
A   B   C1   2   3


BEGIN 当awk处理文件之前,会先执行且执行一次begin后面的脚本代码

awk 'BEGIN {print "hello world begin"} {print $0}' awk.txt

END 在awk处理完文件之后,会执行end后面的脚本代码段

awk '{print $0} END {print "hello world end"}' awk.txt

begin与end一起用

awk 'BEGIN {print "hello world begin"}{print $0}END{print "hello world end"}' awk.txt 
hello world beginThe Zen of Python, by Tim Peters
Beautiful is better than ugly.than
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
A B C D E F
1 2 3 4 5 6
hello world end


head -n 10 /etc/passwd > awk.txt

以:或;或者/作为分隔符

awk -F '[:;/]' '{print $3,$6}' awk.txt

如果是两两一起,则中间显示的是空,比如abc:/abc,显示的是abc abc,空格也算入,$2显示的是空

awk -F '[:;/]' '{print $1,$2,$3}' test


显示自定义内容ip:,要用双引号括起来,对于添加的内容

awk -F :  '{print "hello"$1}' /etc/passwd


把显示出的内容附加到test文件下,注意双引号

awk -F : '{print $3 >> "/root/four/test"}' awk.txt


第二行到第六行之间的第一列内容匹配bin

cat awk.txt | awk -F : '$1 ~ /bin/&&NR > 1 && NR<7 {print $0}'


if的显示内容

awk -F : '{if (($3<3)){print $0}}' awk.txt


查询访问量超过20次的ip

awk '{if ($9 ~ /304|200/) print $1,$9}' access_log | sort | uniq -c | sort -n | awk '{if($1>20)print $2}'


awk的逻辑运算符
> 大于
< 小于
>= 大于等于
<= 小于等于
== 等于
!= 不等于

显示passwd文件下第三列小于5的数据

awk -F ":" '$3 < 5{print $0}' /etc/passwd
awk '{FS=":"}$3<5{print $0}' /etc/passwd

显示第一列为The的内容

awk '$1=="The"{print $1,$2}' awk.txt
awk '{if($1 == "The")print $0}' awk.txt

显示奇数行

awk -F : 'NR %2 ==0{next} {print NR $1}' awk.txt

显示第三行内容

awk -F : 'NR==3{print NR ,$0}' awk.txt

显示第二行到第五行之间的内容

awk -F : 'NR>1&&NR<6{print $0}' awk.txt
awk -F : 'NR==2,NR==5{print $0}' awk.txt


awk的数学运算符
+ 加法
- 减法
* 乘法
/ 除法
% 取余数

求第三列的和

awk -F ":" '{sum+=$3}END {print sum}' awk.txt


FILENAME
awk同时处理两个或以上的文件时,会把文件合并来处理

awk '{print FILENAME,$0}' awk.txt sed.txt


awk的正则表达式
显示包含root的行

awk '/root/{print $0}' awk.txt

符号.代表某个单词、字母以及限定的符号,如果直接匹配符号.则要加\转义

awk '/sy.c/{print $0}' awk.txt

^匹配开头

awk '/^s/{print $0}' awk.txt

$匹配结尾

awk '/sync$/{print $0}' awk.txt

[oa],匹配[]里面的任意单个字符,匹配o或者a,可以[A-Z]、[a-zA-Z],不过要注意语系问题。

awk -F : '/spo[o]l/{print $1}' awk.txt

不显示内容 [^a] 匹配非a的其他内容

awk -F : '/roo[^m]t/ {print $1}' awk.txt   显示的非m,不包括空,也就是说这里不匹配root,必须有个字符
awk -F : '/ro[^m]t/ {print $1}' awk.txt    显示root

*匹配前个字符0次或者多次,+至少匹配一次以上前面的字符,即一个或多个,?匹配0次或1次前面的字符

awk '/u*cp/{print $0}' awk.txt

{2},匹配前面字符2次,也就是要出现两个o。{1,3}出现1到3个前面的字符,{3,}出现至少3个以上前面的字符

awk '/spo{2}l/{print $0}' awk.txt


awk内置函数
length(s) 获取s长度,如果没有s时,获取$0的长度

awk 'length($0)<7{print NR,$0}' awk.txt    查看字符长度小于7的行号和内容

gsub(r,s,t) 在t中用s代替r显示,如果没有t则默认$0

awk -F : 'gsub(/root/,"hello",$0){print $0}' awk.txt  注意hello要带双引号,否则为空
awk -F : 'gsub(/root/,"hello"){print $0}' awk.txt

index(s,t) 显示t在s中的第一个位置

awk 'BEGIN{xy="rootroot";print index(xy,"root")?"yes":"no";}' awk.txt 
awk 'BEGIN{xy="rootroot";print index(xy,"root")}' awk.txtawk '{print NR,index($0,"FTP")}' /etc/passwd

split(s,a,fs) 以fs作为分割符号,把s分割并保存在数组a,如果fs不存在则需要使用当前FS值,也就是空格

date | awk '{split($0,a);print a[1],a[4]}'

match(s,r) s是否匹配r

awk 'match($0,/[0-9]+/) {print $0}' awk.txt 是否包含数字
awk 'match($1,"Simp"){print $0}' awk.txt 是否包含字符Simp

substr(s,p,L) 在s里,从第p个位置开始显示L个字符,字符包括空格

awk '{print substr($0,2,4)}' awk.txt