Linux 第49天 awk

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遍历函数时下标为变量名而非函数名,不要引用错了,否则会提示无法输出函数值


猜你喜欢

转载自blog.51cto.com/winthcloud/2174967