1. 简介
awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。
2. 常用场景
2.1 遍历/etc/passwd所有行,每行内容以":"分隔,打印第二列内容
gawk -F: '{print $1}' /etc/passwd
3. awk命令详解
3.1 awk内置变量
变量名 | 意义 |
---|---|
ARGC | 命令行参数个数 |
ARGV | 命令行参数排列 |
ENVIRON | 支持队列中系统环境变量的使用 |
FILENAME | awk浏览的文件名 |
FNR | 浏览文件的记录数 |
FS | 设置输入域分隔符,等价于命令行 -F选项, 默认是空格 |
NF | 浏览记录的域的个数,即每行列的总数 |
NR | 已读的记录数 |
OFS | 输出域分隔符, 默认是空格 |
ORS | 输出记录分隔符,默认是换行 |
RS | 控制记录分隔符,默认是是换行 |
$0, $1, $2… | $0:整条记录。$1:当前行的第一个域, $2:前行的第二个域… |
$NF | $NF是number finally,表示最后一列的信息 |
FS="\t" 一个或多个 Tab 分隔
awk 'BEGIN{FS="\t+"}{print $1,$2,$3}' tab.txt
FS="[[:space:]+]" 一个或多个空白空格,默认的
awk -F [[:space:]+] '{print $1,$2}' space.txt
OFS 输出字段分隔符
awk 'BEGIN{FS=":";OFS="#"}{print $1,$2,$3}' hello.txt
3.2 BEGIN 和 END 模块
通常,对于每个输入行, awk 都会执行每个脚本代码块一次。然而,在许多编程情况中,可能需要在 awk 开始处理输入文件中的文本之前执行初始化代码。对于这种情况, awk 允许您定义一个 BEGIN 块。
因为 awk 在开始处理输入文件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。
awk 还提供了另一个特殊块,叫作 END 块。 awk 在处理了输入文件中的所有行之后执行这个块。通常, END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。
awk 'BEGIN {count=0;print "[start] user count is ",count} {count=count+1;print $0} END{print "[end] user count is ",count}' passwd
3.3 awk运算符
正则运算符例
awk 'BEGIN{a="100testaa";if(a~/100/) {print "ok"}}'
或
awk 'BEGIN{a="100testaaa"}a~/test/{print "ok"}'
3.4 for 循环
for ( x=1;x<=21;x++ ) {
if ( x==4 ) {
continue
}
print "iteration", x
}
3.5 数组
for…in 输出,因为数组是关联数组,默认是无序的。所以通过 for…in 得到是无序的数组。如果需要得到有序数组,需要通过下标获得。
{
cities[1]=”beijing”
cities[2]=”shanghai”
cities[“three”]=”guangzhou”
for( c in cities) {
print cities[c]
}
print cities[1]
print cities[“1”]
print cities[“three”]
}
3.6 常用字符串函数
替换
awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}'
this is a test!test!
在 info 中查找满足正则表达式, /[0-9]+/ 用”!”替换,并且替换后的值,赋值给 info 未
给 info 值,默认是$0
查找
awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}'
ok #未找到,返回 0
匹配查找
awk 'BEGIN{info="this is a test2010test!";print match(info,/[0-9]+/)?"ok":"no found";}'
ok #如果查找到数字则匹配成功返回 ok,否则失败,返回未找到
截取
awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}'
s is a tes #从第 4 个 字符开始,截取 10 个长度字符串
分割
awk 'BEGIN{info="this is a test";split(info,tA," ");print length(tA);for(k in tA){print k,tA[k];}}'
4 4 test 1 this 2 is 3 a
#分割 info,动态创建数组 tA,awk for …in 循环,是一个无序的循环。 并不是从数组下标
1…n 开始
参照:
https://www.cnblogs.com/ginvip/p/6352157.html