Linux 第49天 awk
时间:20180910
目录
awk
awk options
awk 内置变量
awk printf 定义输出格式
awk 操作符
awk pattern
awk 控制语句
awk 数组
awk 函数
awk 脚本
awk 特殊用法
time命令(测试命令运行速度)
awk练习题
1.统计/etc/fstab文件中每个文件系统类型出现的次数
2.统计/etc/fstab文件中每个单词出现的次数
3.提取出字符串Yd$C@M05MB%9&Bdh7dq+YVixp3vpw中的所有数字
4.有一文件记录了1-100000之间随机的整数共5000个,取出其中最大和最小的整数
5.将文件内容中FQDN取出并根据出现次数从高到低排序
6.以inode为标记,对inode相同的counts进行累加,统计出同一inode中
beginnumber的最小值和endnumber的最大值
本篇总结
awk 文档报告成生器
options
-f 指定一个program-file
-F filed-separator
-v 声明变量
内置变量
FS Fields指定字段分隔符
OFS Output Field Seperator输出分隔符
RS Records 记录分隔符
FNR 输出文件的记录数量一般可在END中使用
NR 输出当前计取第几个记录
NF Number of Fields 一行记录的字段数
FILENAME 当前读取文件的文件名
ARGC 参数的个数
ARGV 数组,保存的是命令所给的各参数
ARGV[01...]
printf 定义输出格式
%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
pattern
一个可以匹配定位行的模式,即可以定位处理哪些行
awk '/regular expression/{action expression}'
控制语句
if(condition){statements;...}else if(condition){statements;...}
while(contition){statements;...}
do{statements;...}while(condition)
for(expr1;expr2;expr3){statements;...}
switch(expression){case VALUE1 or /REGEXP/:statements;case VALUE2...}
break
continue
数组
数据创建时可以直接使用,不需要事先声明
array[index-expression]
weekdays[“mon”]="Monday“
数组遍历
此函数将会遍历数组,var变量则是数组下标
for(var in array){print var,array[var]}
函数
rand() 返回0和1之间的一个随机数
srand() 为rand函数提供新的生成随机数种子
int() 提取所给数值的整数部分
上述三个函数组合便可生成一个随机整数(学艺不精感觉随机数生成不是特别好)
awk 'BEGIN{srand();print int(rand()*100)}'
length() 返回所给字符串的长度
sub(r,s,[t])在t字符串中搜索r模式匹配,并将第一次匹配到的改为s
echo "kjefkj.com" | awk 'sub(/com/,"cn",$1)'
gsub(r,s,[t]) 与上述相同,只是这次只要匹配到就变更
split(s,array,[r]) 以r为分隔符,切割s,并将切割后的结果保存至array数组中,第
一个索引值为1依次类推
system()可以调用shell命令,命令可以执行,其返回值为命令的执行状态码
awk脚本
将awk程序写成脚本,直接调用或执行
示例1(此为program段无法单独执行)
cat f1.awk
{if($3>=100)print $1,$3}
awk -f f1.awk -F: /etc/passwd
示例2(此脚本加执行权限可单独执行)
cat f2.awk
#!/bin/awk -f
if($3>=100)print $1,$3}
chmod +x f2.awk
./f2.awk -F: /etc/passwd
向脚本传递参数
格式: awkfile var=value var2=value inputfile
注意: 在BEGIN过程中不可用。直到首行输入完成以后,变量才可用。可以通过-v参
数,让awk在执行BEGIN之前得到变量的值。命令行中每一个变量都需要一个-v参数
示例
cat test.awk
#!/bin/awk -f
{if($3>=min && $3<=max)print $1,$3}
chmod +x test.awk
./test.awk -F: min=1000 max=1100 /etc/passwd
特殊用法
-F 加多个分隔符 df|awk -F " +|%" '/^\/dev\/sd/{print $1,$5}'
-F "" 分隔符为空时单个字符切
time 此命令可以测试一个命令的执行速度,直接在其后跟上要执行的命令即可
awk练习题
统计/etc/fstab文件中每个文件系统类型出现的次数
awk '/^[^ #]/{type[$3]++}END{for(I in type)print I,type[I]}' /etc/fstab
统计/etc/fstab文件中每个单词出现的次数
awk '{for(i=1;i<=NF;i++)word[$i]++}END{for(I in word)print I,word[I]}'
/etc/fstab(此为一行内容)
提取出字符串Yd$C@M05MB%9&Bdh7dq+YVixp3vpw中的所有数字
echo 'Yd$C@M05MB%9&Bdh7dq+YVixp3vpw'|awk -F ""
'{for(i=1;i<=NF;i++)if($i>=0&&$i<=9)print $i}' (两行为一条命令)
有一文件记录了1-100000之间随机的整数共5000个,存储的格式100,50,35,89…请取出
其中最大和最小的整数
生成随机数
(echo -e "$RANDOM\c";for((i=1;i<100;i++));do echo -e
",$RANDOM\c";done)>html (两行为一行内容)
取最大值最小值
awk -F "," '{min=$1;max=$1;for(i=1;i<=NF;i++){if($i>=max){max=$i}
else if(min>=$i)min=$i}print min,max}' html (两行为一条命令)
将以下文件内容中FQDN取出并根据其进行计数从高到低排序
http://mail.baidu.com/index.html
http://www.baidu.com/test.html
http://study.linux.com/index.html
http://blog.linux.com/index.html
http://www.baidu.com/images/logo.jpg
http://blog.linux.com/20080102.html
awk -F "/" '{url[$3]++}END{for(i in url)print url[i],i}' html|sort -nr
将以下文本以inode为标记,对inode相同的counts进行累加,并且统计出同一inode中
beginnumber的最小值和endnumber的最大值
inode|beginnumber|endnumber|counts|
106|3363120000|3363129999|10000|
106|3368560000|3368579999|20000|
310|3337000000|3337000100|101|
310|3342950000|3342959999|10000|
310|3362120960|3362120961|2|
311|3313460102|3313469999|9898|
311|3313470000|3313499999|30000|
311|3362120962|3362120963|2|
输出的结果格式为:
310|3337000000|3362120961|10103|
311|3313460102|3362120963|39900|
106|3363120000|3368579999|30000|
[root@Cent7 class]# cat awk.inode
NR!=1{
inode[$1]+=$4
if(!benu[$1]){benu[$1]=$2}else if(benu[$1]>$2){benu[$1]=$2}
if(!ednu[$1]){ednu[$1]=$3}else if(ednu[$1]<$3){ednu[$1]=$3}
}
END{
for(i in inode)print i"|"benu[i]"|"ednu[i]"|"inode[i]
}
[root@Cent7 class]# awk -F "|" -f awk.inode inode
310|3337000000|3362120961|10103
311|3313460102|3362120963|39900
106|3363120000|3368579999|30000
本篇总结
awk是一个其于用户所给的模式来处理一行的内容
awk将每一行分成若干个段,可以基于每一个段来做处理动作
awk有BEGIN,END两个段用来在处理所给文档之前和之后做其它的额外的操作
awk遍历函数时下标为变量名而非函数名,不要引用错了,否则会提示无法输出函数值