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