awk处理信息前,会先将文本格式化,意即用域分隔符划分抽取域,分隔符可能是任意字符。
有三种方式调用awk:
1.命令行方式 awk [-F field-separator] 'commands' input-file(s) 其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。 在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。 2.shell脚本方式 将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。 相当于shell脚本首行的:#!/bin/sh 可以换成:#!/bin/awk 3.将所有的awk命令插入一个单独文件,然后调用: awk -f awk-script-file input-file(s) 其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。
在命令中调用a w k时,a w k脚本由各种操作和模式组成。
如果设置了 - F选项,则 a w k每次读一条记录或一行,并使用指定的分隔符分隔指定域,但如果未设置- F选项,a w k假定空格为域分隔符,并保持这个设置直到发现一新行。当新行出现时,a w k命令获悉已读完整条记录,然后在下一个记录启动读命令,这个读进程将持续到文件尾或文件不再存在。
模式和动作
任何awk语句都是有模式和动作组成.在一个awk脚本中可能有很多语句,模式部分决定动作语句何时触发以及出发时间.处理即对数据进行的操作.如果省略模式部分,动作将时刻保持执行状态.模式可以是任何条件语句或符合语句或正则表达式.模式包括两个特殊字段BEGIN和END.使用BEGIN语句设置计数和打印头.BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作一句输入文本开始执行.END语句用来在awk完成浏览动作后打印输出文本总数和结尾状态标识.
域和记录
使用$1,$3表示参照第一个和第三个域,注意这里使用逗号做域分割,如果希望打印一个有5个域的记录的所有域,可使用$0,意即所有域.
为打印一个域或所有域,使用print命令,这是一个awk动作
模式和动作
模式:两个特殊段BEGIN和END
动作:实际动作大多在{}内指明
输出:
1.抽取域
命令:awk -F: '{print $1}' /etc/passwd
输出:打印/etc/passwd目录下的所有用户名
2.保存输出
awk -F: ‘{print $1}’ /etc/passwd |tee user 使用tee命令,在输出文件的同时,输出到屏幕
3.使用标准输出
awk -F : ‘{print $1}’ /etc/passwd > user3
4.打印所有记录
awk -F : ‘{print $0}’ /etc/passwd
5.打印单独记录
awk -F: ‘{print $1,$4}’ /etc/passwd
6.打印报告头
awk -F : ‘BEGIN{print “NAME\n”}{print $1}’ /etc/passwd
7.打印结尾
awk -F: ‘{print $1}END{print “this is all users\n”}’ /etc/passwd
awk中正则表达式用法
这里正则表达式用斜线括起来。例如,在文本文件中查询字符串 G r e e n,使用/ G r e e n /可以查出单词G r e e n的出现情况
元字符
这里是 a w k中正则表达式匹配操作中经常用到的字符。
\ ^ $ . [] | () * + ?
这里有两个字符,它们只适用于 a w k而不适用于 g r e p或s e d。它们是:
+ 使用+匹配一个或多个字符。
? 匹配模式出现频率。例如使用 /X Y?Z/ 匹配X Y Z或Y Z。
条件操作符
1.匹配
awk -F : '{if($1~/root/) print}' /etc/passwd
分析:if($1~/roo/t) 表示如果file中包含root,打印他
2.精确匹配
使用符号==
awk -F: '{if($3==0) print}' /etc/passwd
3.不匹配
!~
awk -F: '{if($1!~/linuxone/) print}' /etc/passwd
精确不匹配
!=
awk -F: '{if($1!=/linuxone/) print}' /etc/passwd
4.小于
<
5.小于等于
<=
6.大于
>
7.设置大小写
awk ‘/[Rr]oot’ /etc/passwd
8.任意字符
awk -F : '{f($1~/^...t/) print}' /etc/passwd
分析:if($1~/^...t/)表示第四个字母是t
9.或关系匹配
awk -F : '{if($1~/(squid|nagios)/) print}' /etc/passwd
10.行首
awk '/^root/' /etc/passwd
分析:^root(行首包含root)
11 AND &&
awk -F : '{if($1=="root"&&$3=="0") print}' /etc/passwd
12.OR ||
内置变量:
变量名 | 含义 |
ARCC | 命令行参数个数 |
ARGV | 命令行参数列表 |
ENV |RON | 支持队列中的系统环境变量的使用 |
FNR | 浏览文件的记录数 |
FS | 置顶分隔符,等价于-F |
NF | 浏览记录的域的个数 |
NR | 一度的记录数 |
OFS | 输出域分隔符 |
ORS | 输出记录分隔符 |
RS | 控制记录分隔符 |
案例:
打印有多少行记录
awk 'END{print NR}' /etc/passwd
设置输入域到变量名
awk -F : '{name=$1;path=$7; if(name~/root/)print name"\tpath is : " path}' /etc/passwd
域值比较操作
awk '{if($6<$7) print $0}' input-file
修改文本域只显示修改的记录
awk -F : '{if($1=="root"){$1="nagios server" ; print}}' /etc/passwd
文件长度相加
ls -l | awk '/^[^d]/ {print $9"\t" $5}{tot+=$5}\
END {print "total kb:"tot}'
内置的字符串函数
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 |
sub(s,) | 用$0中最左边也是最长的字符串替代 |
subtr(s,p) | 返回字符串s中从p开始的后缀部分 |
substr(s,p,n) | 返回字符串s中从p开始长度为n的后缀部分 |
1.gsub
awk 'gsub(/^root/,"netseek") {print}' /etc/passwd #将以root开头的字符串替换为netseek并打印
awk 'gsub(/0/,2){print}' /etc/passwd
awk '{print gsub(/0/,2) $0}' /etc/fstab
2.index
awk 'BEGIN{print index("root","o")}' #查询o在root字符串中出现的第一位置
awk -F : '$1=="root" {print index($1,"o")" " $1}' /etc/passwd
awk -F : '{print index($1,"o") $1}' /etc/passwd
3.length
awk -F : '{print length($1)}' /etc/passwd
wk -F : '$1=="root"{print length($1)"\t" $0}' /etc/passwd
4.match(在ANCD中查找C的位置)
awk 'BEGIN{print match("ANCD","C")}'
5.split返回字符串数组元素个数
awk 'BEGIN{print split("123#456#789",array,"#")}'
6.sub只能替换指定域的第一个0
awk 'sub(/0/,2){print }' /etc/fstab
7.substr 按照起始位置以及长度返回字符串的一部分
awk 'BEGIN{print substr("www.baidu.com",5,9)}' #第五个子夫开始,取9个字符
awk 'BEGIN{print substr("www.baidu.com",5)}' #第五个位置开始,一直到最后
字符串屏蔽序列
符号 | 含义 |
\b | 退格符 |
\f | 走纸换页 |
\n | 新行 |
\r | 回车 |
\t | tab键(四个空格) |
\c | 任意其他特殊字符 |
\ddd | 八进制 |
案例:
awk -F : '{print $1,"\b" $2,"\t" $3}' /etc/passwd
分析:print和printf两者效果不同
printf修饰符
- : 左对齐
width : 域的步长0表示0步长
.prec : 最大字符串长度,或小数点右边的位数
awk printf格式
符号 | 含义 |
%c | ASCII字符 |
%d | 整数 |
%e | 科学计数法 |
%f | 浮点数 |
%g | awk决定使用哪种浮点数转换,e或者f |
%o | 八进制数 |
%s | 字符串 |
%x | 十六进制 |
1.字符串转换
echo "65" | awk '{printf "%c\n", $0}'
awk 'BEGIN{printf "%c\n" ,65}'
awk 'BEGIN{printf "%f\n",999}'
2.格式化输出
awk -F : '{printf "%-15s %s\n",$1,$3}' /etc/passwd
awk -F : 'BEGIN{printf "USER\t\tUID\n"}{printf "%-15s %s\n",$1,$3}' /etc/passwd