标签:awk 文本处理工具
Awk
名称来源: Aho, Weinberger, Kernighan 三个开发者名字首字母,但现在我们使用的版本已经不是原始的AWK了。而是GUN组织后来编写的开源的,所以全名应该是GAWK。
基本用法:
gawk[OPTIONS] ‘program‘ FILE1 FILE2 ...
program: PATTERN{ACTION STATEMENT}
ACTION: print, printf
选项:
-F: 指明输入字段分隔符
-v VAR_NAME=VALUE: 变量赋值;
-f /PATH/FROM/AWK_SCRIPT:
1、awk的输出命令之一:print
用法:print item1, item2, ...
item可以为字符串,也可以为变量
要点:
(1) 各item之间需要使用逗号分隔;而输出时的分隔符为默认为空白字符;
(2) 输出的各item可以为字符串或数值、当前记录的字段($#)、变量或awk的表达式;数值会被隐式转换为字符串进行输出;
(3) print后面的item省略时,相当于运行“print $0”,用于输出整行;
(4) 输出空白字符:print " "
变量类型:
内置变量:
FS:输入分隔符,默认为空白字符
RS:输入换行符,默认为换行符
OFS:输出分隔符,默认为空白字符
ORS:输出换行符,默认为换行符
NF:当前行的字段数
print NF:显示当前字段数
Print $NF:显示最后一个字段
NR:行数;命令后跟的所有文件将统一计数
Print NR:显示行数
FNR:行数;各文件分别计数
FILENAME:当前正被awk读取的文件的文件名
ARGC:awk命令行中的参数的个数(program不算参数)
ARGV:数组,保存了命令行参数(program不算参数)
awk ‘{print ARGV[0]}‘ /etc/passwd :则显示第一个参数 awk
awk ‘{print ARGV[1]}‘ /etc/passwd :则显示第二个参数/etc/passwd
自定义变量:
-v VAR_NAME=VALUE
可在选项中定义变量;也可以在program中定义变量
awk -vname=tom ‘{print name}‘ /etc/passwd
awk ‘{name="tom";print name}‘ /etc/passwd
2、awk的输出命令之二: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:显示无符号整数;
%%: 显示%符号自身;
修饰符:
#[.#]:
左边的#:用于指定显示宽度;
右边的#: 显示精度;
+:显示数值符号
-:左对齐
操作符
算术操作符:
x+y, x-y, x*y, x/y, x^y, x%y
-x: 负值
+x: 转换为数值
字符操作符:字符串连接 (空格)
赋值操作符:
=, +=, -=, *=, /=, %=, ^=
++, --
比较操作符:
>, >=, <, <=, ==, !=
模式匹配操作符:
~:是否能由右侧指定的模式所匹配;
!~:是否不能由右侧指定模式所匹配;
逻辑操作符:
&&:与运算
||: 或运算
条件表达式:
selector?if-true-expression:if-false-expression(若selector为真,则执行if-true-expression,若为假,则执行if-false-expression)
例如: awk -F: ‘{$3>=500?type="commonuser":type="sysuser";printf "%20s -is-%-s\n",$1,type}‘ /etc/passwd
函数调用:
function_name(argu1, argu2, ...)
PATTERN
(1)empty:空模式,匹配所有行;
(2)/Regular Expression/:仅将ACTION应用于能够被正则表达式所匹配到的行;
例如:awk ‘/^root/{print }‘ /etc/passwd 显示root这行
(3)relational expression:关系表达式,即结果为“真”、“假”的表达式,或者其结果能类同于“真”或“假”的表达;一般来说,其结果为非0数值或非空字符串即可类同为“真”,否则,则类同为“假”;
例如:awk -F: ‘$3>=500{print $1,$3}‘/etc/passwd 显示UID大于等于500的,用户名和UID
例如:awk -F: ‘$1~/root/{print $1,$3}‘/etc/passwd 显示第一个字段能和root匹配的用户名和UID
(4)line ranges:行范围,类似sed或vim中的地址定界方式
startline,endline
(5)BEGIN/END:两个特殊模式
BEGIN:在文件格式化操作开始之前事先执行的一次操作;通常用于输出表头或做出一个预处理操作;
END:在文件格式操作完成之后,命令退出之前执行的一次操作;通常用于输出表尾或做出清理操作;
例子:awk ‘BEGIN{print"xxxxxxxxxxxxxxxxxxxxxx"}{print "yyyyyyyyyyyyy"}END{print"xxxxxxxxxxxxxxxxxxxxx"}‘ /etc/fstab
BEGIN中的内容在{print"yyyyyyyyyyyyy"}之前执行一次
{print "yyyyyyyyyyyyy"}执行的次数为/etc/hosts文件的行数
END中的内容在{print"yyyyyyyyyyyyy"}之后执行一次
常用ACTION
(1) EXPRESSIONS:条件表达式,例如变量赋值
(2) Control Statements:控制语句,如if, while等;
(3) Compound Statements:复合语句
(4) input statements:输入语句
(5) output statements:输出语句
控制语句
if (condition) { statements } [else { statement }]
while (condition) { statements }
do statement while (condition)
for(expr1;expr2;expr3) { statements }
for(var in array) { statements }
switch (expression) {case VALUE or /REGEXP/: statement;...; default: statementN}
break
continue
delete array[index]
delete array
exit [ expression ]
{ statements }
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 if-else条件判断
语法:if (condition) statement [ else statement ]
if (condition) {statements} [else {statements}]
使用场景:对awk取得的整行或行中的字段做条件判断;
2while循环
语法:while (condition) statement
while (condition) {statements}
条件为“真”时循环,为“假”时退出循环;
使用场景:通常用于在当前行的各字段间进行循环;
awk -F: ‘{i=1;while(i<=NF){if(length($i)>=6) {printf "%s %s",$i," "};i++};print" "}‘ /etc/passwd
3do-while循环
语法:do statement while (condition)
do {statements} while (condtion)
意义:至少执行一次循环体
4for循环
语法:for (expr1;expr2;expr3) statement
for (expr1;expr2;expr3) {statements}
for (variable assignment;codition;iterationprocess) {for-body}
# awk ‘{for(i=1;i<=NF;i++){if(length($i)>=6)print $i}}‘ /etc/issue
第二种用法:用于遍历数组中的元素
for (var_name in array) {for-body}
5swtich
语法:switch (expression) {case VALUE or/REGEXP/: statement; ...; default: statementN}
6break and continue
break [n]:退出当前循环,n是一个数字,用于指定退出几层循环;
continue:提前结束本轮循环而进入下一轮;
7next
提前结束对本行文本的处理,而提前进入下一行的处理操作;
# awk -F: ‘{if($3%2==0) next;print $1,$3}‘/etc/passwd
数组
关联数组:array[index-expression]
index-expression:
可以使用任意字符;
如果某数组元素事先不存在,则在引用时,awk会自动创建此元素并将其值初始化为空串;
因此,若要判断数组中的某元素是否存在,要使用“index in array”的方式进行判断;
要遍历数组中的元素,则要使用for (var_name in array)的方式进行;此时,var_name会遍历array的每个索引,所以,要显示数组元素的值,要使用array[var_name]
统计整个文件,每个单词出现的次数:
# awk ‘{for(i=1;i<=NF;i++){count[$i]++}}END{for(j in count) {print j,count[j]}}‘/root/count.txt
每行单独统计,每个单词出现的次数:
# awk ‘{for(i=1;i<=NF;i++){count[$i]++};for(j in count) {print j,count[j]};delete count}‘ /root/count.txt
统计当前系统上所有tcp连接的各种状态的个数:
# ss -tan | awk‘!/^State/{state[$1]++}END{for(i in state) print i,state[i]}‘
统计指定的web访问日志中各ip的资源访问次数:
# awk ‘{ip[$1]++}END{for(i in ip) printi,ip[i]}‘ /var/log/httpd/access_log
函数:内建函数和用户自定义函数
内建函数
数值处理:
rand():返回0至1之间的一个随机数;
字符串处理:
length([s]):返回指定的字符串的长度;
sub(r,s[,t]):基于r所表示的模式来匹配字符串t中的内容,将其第一次被匹配到的内容替换为s所表示的字符串;
gsub(r,s[,t]):基于r所表示的模式来匹配字符串t中的内容,将其所有被匹配到的内容均替换为s所表示的字符串;
split(s,a[,r]):以r为分隔符去切割字符串s,并将切割后的结果保存至a表示的数组中;
例如:# awk‘{split($0,userinfo,":");print userinfo[1]}‘ /etc/passwd
首先用“:”分割/etc/passwd的每行,并保存在userinfo属组中,然后打印出userinfo数组第一个内容,即每行的用户名
注意:awk的数组下标从1开始编号
substr(s,i[,n]):从s所表示的字符串中取子串,取法:从i表示的位置开始,取n个字符;
时间类函数:
systime():取当前系统时间,结果形式为时间戳;
用户自定义函数
function f_name(p,q) {
...
}
本文出自 “Linux” 博客,请务必保留此出处http://laoliao.blog.51cto.com/10027070/1658648
标签:awk 文本处理工具
原文地址:http://laoliao.blog.51cto.com/10027070/1658648