awk的工作模式:在处理文本流时,每一次从文本中读取一行数据,按指定的分隔符,对整行内容进行切片,把切片的结果赋值给内置的位置参数变量,然后可以指定对特定的字段做出特定的处理后输出。
基本语法:awk [OPTION] 'program' FILE1 FILE2....
其中program的组成方式为:PATTERN{ACTION STATEMENT},最常用的ACTION有print,printf
awk的运行方式
1,命令行
#awk -F: '{print $1,$3}' /etc/passwd
2,awk程序文件
root@localhost ~]# vim awk.script {print $1,$3} [root@localhost ~]# awk -f awk.script -F: /etc/passwd
3,awk脚本(不常用)。
awk的常用选项
-F[]:指明字段分隔符
-v VAR_NAME=VALUE:变量赋值
-f /PATN/TO/AWK_SCRIPT
输出命令print
用法:print item1,item2...
item的类型可以分为以下几类:字符串、变量、数值。
1、字符串:需要用引号引用,如:print “hello”
[root@localhost ~]# awk -F: '{print "hello",$1}' /etc/passwd
2、变量,需要注意的是,要显示变量值只需要print VAR_NAME即可,不需要加$,这点跟BASH有所不同,一定要搞清楚。引用变量只需使用变量名。
[root@localhost ~]# awk -v f1=hello '{print f1}' /etc/passwd
[root@localhost ~]# awk -F: -v f1=1 '{print $f1}' /etc/passwd
3、数值,无需加引号
[root@localhost ~]# awk '{print 3}' /etc/passwd
注意:各item之间用“,”分隔,输出的分隔符为“ ”
(1) 各item之间需要使用逗号分隔;而输出时的分隔符为默认为空白字符;
(2) 输出的各item可以为字符串或数值、当前记录的字段($#)、变量或awk的表达式;数值会被隐式转换为字符串进行输出;
(3) print后面的item省略时,相当于运行“print $0”,用于输出整行;
(4) 输出空白字符:print " "
变量
内建变量,自定义变量
内建变量:
FS,RS,OFS,ORS,NF,NR,FNR
1、 FS:input Field Seperator,输入字段分隔符,默认为空白
[root@localhost ~]# awk -v FS=":" '{print $1,$3}' /etc/passwd
使用FS可指定多重分隔符
[root@localhost ~]# vim awktest what are you doing? what is your name? this is hank,lily.
2、RS:input Recore Sperator,输入时的行分隔符,默认为换行符。
[root@localhost ~]# awk -v RS=" " '{print $0}' /etc/passwd
3、OFS:输出时的字段分隔符,默认为空白。
4、ORS:输出时的行分隔符,默认为换行符。
5、NF:Number of field in current record,当前行的字段数。
显示文本中每一行的最后一个字段
NR:Number of record,行数,命令后跟的所有文件将统一计数。
FNR:文件的行数,各文件单独计数。
FILENAME:当前正在被awk读取的文件的文件名
ARGC:awk命令行中参数的个数,‘program’和“file”都被定义为参数
ARGV:保存命令行参数本身
自定义变量
1、-v VAR_NAME=VALUE
2、在‘program’中定义。
输出语句printf
语法:printf FORMAT,item1,item2,...
要点:
(1) 必须提供FORMAT;
(2) 与print语句不同,printf不会自动换行,需要显式指定换行符:\n
(3) FORMAT中需要分别为后面的每个item指定一个格式符,否则item则无法显示;
格式符:都以%开头,后跟单个字符; %c: 显示字符的ASCII码; %d, %i:显示为十进制整数; %e, %E: 科学计数法显示数值; %f:显示为浮点数; %g, %G:以科学计数法或浮点数格式显示数值; %s: 显示为字符串; %u:显示无符号整数; %%: 显示%符号自身;
不为item指定格式符,item无法输出
修饰符: #[.#]: 左边的#:用于指定显示宽度; 右边的#: 显示精度; +:显示数值符号 -:左对齐
操作符
算术操作符: x+y, x-y, x*y, x/y, x^y, x%y -x: 负值 +x: 转换为数值 字符操作符:字符串连接 赋值操作符: =, +=, -=, *=, /=, %=, ^= ++, -- 比较操作符: >, >=, <, <=, ==, != 模式匹配操作符: ~:是否能由右侧指定的模式所匹配; !~:是否不能由右侧指定模式所匹配; 逻辑操作符: &&:与运算 ||: 或运算 条件表达式: selector?if-true-expression:if-false-expression
1、算术操作符
2、字符串操作符,字符串连接
3、赋值操作符
4、条件表达式
PATTERN
(1) empty:空模式,匹配所有行; (2) /Regular Expression/:仅将ACTION应用于能够被Regular Expression所匹配到的行; 例如:awk -F: '/^[ab]/{print $1,$3}' /etc/passwd (3) relational expression:关系表达式,即结果为“真”、“假”的表达式, 或者其结果能类同于“真”或“假”的表达;一般来说,其结果为非0数值或非空字符串即可类同为“真”,否则,则类同为“假”; 例如:awk -F: '$3>=500{print $1,$3}' /etc/passwd 例如:awk -F: '$1~/root/{print $1,$3}' /etc/passwd (4) line ranges:行范围,类似sed或vim中的地址定界方式 startline,endline 5) BEGIN/END:两个特殊模式 BEGIN:在文件格式化操作开始之前事先执行的一次操作;通常用于输出表头或做出一个预处理操作; END:在文件格式操作完成之后,命令退出之前执行的一次操作;通常用于输出表尾或做出清理操作;
行范围
常用的ACTION
(1) EXPRESSIONS:例如变量赋值 (2) Control Statements:控制语句,如if, while等; (3) Compound Statements:复合语句 (4) input statements (5) output statements
控制语句
if-else
语法:if (condition) statement [ else statement ]
if (condition) {statements} [else {statements}]
图43
[root@localhost ~]# awk -F: '{if ($3>=500){print $1,"common"} else {print $1,"sys"}}' /etc/passwd
while循环
语法:while (condition) statement while (condition) {statements}
通常用于在当前行的各字段间进行循环
for循环
next
显示ID号为奇数的用户
数组
统计一个文件中每个单词出现的次数
[root@localhost ~]# awk -F: '{for(i=1;i<=NF;i++) {count[$i]++}}END{for(j in count) {print j,count[j]}}' /etc/passwd
统计一个文件中每一行每个单词出现的次数
# awk '{for(i=1;i<=NF;i++) {count[$i]++};for(j in count) {print j,count[j]};delete count}' /root/count.txt