1、awk的调用方式
a、命令行方式 awk -F: 'commands' input-file
b、将awk命令插入文件,并使其可执行,然后用awk命令解释器做为脚本的行首,便通过键入脚本名来调用它
c、将awk命令插入文件,然后调用 awk -f awk-script-file input-files
2、模式和动作
awk语句 = 模式 +动作
模式:决定动作语句何时触发及触发事件 (任何条件语句、复合语句、正则表达式) 两个字段:BEGIN+END
动作:即对数据进行的操作(在{}中指明,大多用来打印)
BEGIN(设置计数和打印头,使用在任何文本浏览动作前)
END(在awk完成文本浏览动作后打印输出文本总数和结尾状态标志)
3、域和记录
3-1、抽取域
3-2、保存awk输出
awk '{print $0}' grade.txt >wow
3-3、使用标准输入
belts.awk grade_student.txt
belts.awk < grade.txt
grade.txt | belts.awk
3-4、打印所有记录
awk '{print $0}' grade.txt 没有模式部分,只有动作部分{print $0},必须使用花括号
3-5、打印单独记录
awk ‘{print $1,$2} ' grade.txt
3-6、打印报告头
awk ‘BEGIN {print ”Name Belt\n---------------------------------------------------------------"} {print $1"\t"$4}’ grade.txt
3-7、打印信息尾
awk ‘BEIGN {print ”Name\n---------------"} {print $1} END {"------------------\nend-of-report"}’ grade.txt
3-8、错误信息提示
碰到awk错误时,查找
---确保整个awk命令用单引号括起来
---确保命令内所有引号成对出现
---确保用花括号动作语句,用圆括号条件语句
---不要忘记使用花括号
3-9、awk键盘输入
当awk命令行忘记输入文件,awk最终停止操作并等待,可顺序输入文本,并ctrl+d结束,该操作不常用
4、awk中正则表达式及其操作
使用正则表达式时用斜线括起来,例如/Green/
5、元字符
\ ^ $ . [] | () * + ? 其中有2个字符只使用与awk而不使用于grep或sed
+ 匹配一个或多个字符
? 匹配模式出现频率
6、条件操作符
< <= >= == !=
~ 匹配正则表达式
!~ 不匹配正则表达式
6-1 匹配
可用~,也可用if(),
如 awk '{if($4~/Brown/) print $0}' grade.txt 找到时,若不特别声明则缺省打印整条记录
同上 awk '$0~/Brown/' grade.txt 匹配到记录时,只打印模式brown
6-2 精确匹配
awk '$3=="48" {print $0}' grade.txt
6-3 不匹配
awk '$0 !~ /brown/ ' grade.txt
awk '{if($4 !~ /brown/) print $0}' grade.txt
awk '$4 != "brown-2" {print $0}' grade.txt
awk '$4 != "brown-2" {print $0}' grade.txt
6-4 小于
awk '{if($6<$7) print $0 "$1 try better at the next comp"}'
6-5 小于等于
awk '{if($6 <= $7) print $1}' grade.txt
6-7 大于
awk '{if($6 > $7) print $1}' grade.txt
6-8 设置大小写
awk '[Gg]reen' grade.txt
6-9 任意字符
awk '$1~/^...a/' grade.txt
6-10 或关系匹配
awk '$4~/Green|Yellow/' grade.txt
6-11 行首
awk '/^48/' grade.txt
6-12 AND &&
awk '{if($4~/Brown/ && $6>$7) print $0}' grade.txt
awk '$4~/Brown/ && $6 > $7' grade.txt
6-13 OR ||
awk '{if($4~/Brown/ || $6>$7) print $0}' grade.txt
awk '$4~/Brown/ || $6 > $7' grade.txt
6-14 !
7、awk内置变量
可设置环境信息
ARGC 命令行参数个数
ARGV 命令行参数排列,是ARGC的参数排列数组,其中每个元素ARGV[n],n为期望访问的命令行参数
ENVIRON 支持队列中系统环境变量的使用,单独访问系统变量时使用实际变量名,如:ENVIRON["EDITOR"]="vi"
FILENAME awk浏览的文件名,浏览前该变量为空,
FNR 浏览文件的记录数,当前操作的记录数,其变量值<=NR
FS 设置输入域分隔符,等价于命令行的-F选项,缺省为空格,若使用逗号,为FS=","
NF 浏览记录的域个数,记录被读后再设置
NR 已读得记录数
OFS 输出域分隔符,缺省为空格,若设置为#,OFS="#"
ORS 输出记录分隔符,缺省为新行\n
RS 控制记录分隔符,缺省为新行\n
8、NF、NR和FILENAME
NR需放到END语法中去,如 awk 'END {print NR}' grade.txt
打印出记录支持域个数、当前操作记录数、最后显示文件名,如 awk '{print NF NR $0} END {print FILENAME}' grade.txt
打印记录前判断是否为空以及其他条件 如 awk '{if(NR>0 && $4~/Brown/) print $0}' grade.txt
显示当前目录名 如 pwd | awk -F/ '{print $NF}'
或显示文件名 如 echo "/home/zhangweiwei/script/belts.awk" | awk -F/ '{print $NF}'
9、AWK操作符
赋值操作符 = += -= *= /= %= ^=
条件表达式操作符 ?
或、与、非 || && !
匹配操作符 ~ !~
关系操作符 < <= == > >= !=
算术操作符 + - * / % ^
前缀和后缀 ++ --
9-1 设置输入域到域变量名
zhangweiwei@linux-3raj:~/script> awk '{name=$1;belts=$4; if(belts~/Yellow/) print name" is belt"blets}' grade.txt
P.Bunny is belt
9-2 域值比较操作
awk '{if($6 < 30) print $0}' grade.txt
改成:awk 'BEGIN {BASELINE="30"}{if($6<BASELINE) print $0}' grade.txt 这里使用BEGIN语法,在awk表达式改动时减少麻烦
9-3 修改数值域取值
awk '{if($1~/Bunny/) $6=$6-1;print $0}' grade.txt
9-4 修改文本域
awk '{if($1~/Bunny/) ($1="P.Bunny1");print $0}' grade.txt 修改字符串时要用(" ")语法
9-5 只显示修改记录
awk '{if($1~/Bunny/) {$1="P.Bunny1";print $1}}' grade.txt 使用{}将修改语句及打印语句单独括起来
9-6 创建新的输出域
awk 'BEGIN {print "Name\t Difference"}{if($6<$7) {$8=$7-$6; print $1,$8}}' grade.txt
或 awk 'BEGIN {print "Name\t Difference"}{if($6<$7) {diff=$7-$6; print $1,diff}}' grade.txt
9-7 增加列值
统计目前级别分: awk '(tol+=$6); END {print "Club student total points :"tol}' grade.txt
避免显示所有记录:awk '{(tol+=$6)}; END {print "Club student total points :" tol}' grade.txt
9-8 文件长度相加
ls -l|awk '/^[^d]/ {print $9"\t"$5} {tol+=$5} END {print "total kB:" tol}'
10 内置字符串函数
gsub(r,s) 整个$0中用s替代r
gsub(r,s,t) 整个t中用s替代r
index(s,t) 返回s中字符串t的第一位置
length(s) 返回s的长度
match(s,r) 测试s是否包含匹配r 的字符串
split(s,a,fs) 在fs上将s分成序列a
sprint(fmt,exp) 返回经fmt格式化后的exp
sub(r,s) 用$0中最左边最长的子串代替s
substr(s,p) 返回字符串s中从p开始的后缀部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分
10-1 gsub(r,s)
awk 'gsub(/4842/,4899) {print $0}' grade.txt 使用正则表达式格式,/目标模式/ 替换模式
10-2 index(s,t)
awk 'BEGIN {print index("Bunny","unny")}' grade.txt
10-3 length(s)
awk '{print $1,length($1)}' grade.txt
awk 'BEGIN {print "name\t length"} {$8=length($1);print $1,$8}' grade.txt
10-4 match(s,r)
awk '{print $1,match($1,"l")}' grade.txt --显示出第一列以及其中字符l出现的位置
10-5 split(s,a,fs)
awk 'BEGIN {print split("123#345#789#0123", myarray, "#")}' 使用分隔符分隔后返回数组元素个数
10-6 sub(r,s)
awk '$1="J.Troll" sub(/26/,"29",$0)' grade.txt 显示$1为J.Troll用户第一个26转换为29
10-7 substr(s,p,n)
awk '{print substr($1,2,5)}' grade.txt 或省略抽取长度 awk '{print substr($1,2)}' grade.txt
awk '{print substr($0,2,99)}' grade.txt 如果抽取长度远大于记录总长度,显示所有,或省略抽取长度 awk '{print substr($0,2)}' grade.txt
awk 'BEGIN {test="abcdefghijklmn"} END {print substr(test,2)}' grade.txt
10-8 从shell中向awk传入字符串
echo "abcdefghijklmn" | awk '{print substr($0,2)}'
pwd | awk '{print length($0)}'
11 字符串屏蔽序列
\t tab键
\f 走纸换页
\n 新行
\r 回车键
\ddd 八进制值
\c 任意其他特殊字符,例如 \\
\b 退格键
awk 'BEGIN {print "\nMay\tDay\nMay\t\104\141\171"}'
12 awk输出函数printf
格式 printf [格式控制符], 参数
格式控制符通常在""中,都以%符号开头,以决定转换的字符结束
13 printf修饰符
修饰符: - 左对齐 Width 域的步长 .prec 最大字符串长度或小数点右边的位数
printf格式:
%c ASCII字符
%d 整数
%e 浮点数,科学计数法
%f 浮点数
%g awk决定使用哪种浮点数转换e或f
%o 八进制数
%s 字符串
%x 十六进制数
13-1 字符转换
echo "65" | awk '{printf "%c\n",$0}'
awk 'BEGIN {printf "%c\n",65}'
awk 'BEGIN {printf "%f\n",65}'
13-2 格式化输出
awk '{printf "%-15s %s\n",$1,$3}' grade.txt
awk 'BEGIN {print "Name \t\tS.Number"}{printf "%-15s %s\n",$1,$3}' grade.txt
13-3 向一行awk命令传值
awk 命名变量=输入文件值
awk '{if($5<AGE) print $0}' AGE=10grade.txt
df -k | awk '$4~/^[0-9]/ {if($4>trigger) print $6"\t"$4}' trigger=56000
who | awk '{print $1" is logon"}'
who | awk '{if($1==user) print $1" is are connected"}' user=$LOGNAME
13-4 awk脚本文件
第一行 !/bin/awk -f 如:
!/bin/awk -f
begin{
print "Student Date MemberNo. Grade Age Points Max"
print "Name Joined Gained Point Available"
print "============================================================="
}
(tot+=$6)
END{print "Club student total points :" tot print "Average Club Student points: " tot/NR}