习题
awk打印奇/偶数行
/* sed实现 */
seq 10|sed -n "1~2p"
seq 10|sed -n "2~2p"
/* awk实现 */
seq 10|awk 'i=!i'
seq 10|awk '!(i=!i)'
筛选访问量超过80的ip()
awk '{print $1}' ./access_log|sort|uniq -c|sort -nr|awk '$1>=80{print}'
随机取100个数,找出最大和最小值
/* 生成随机数 */
(echo -n "$RANDOM";for((i=0;i<100;i++));do echo -n ",$RANDOM";done )>./random.txt
/* 比较 */
awk -F"," '{max=$1;min=$1;i=2;while(i<=NF){if($i>max){max=$i}else if($i<min){min=$i};i++;}} END {print "Max="max"\n""Min="min}' random.txt
/* 检查 */
cat random.txt|tr "," "\n" |sort -nr
awk实现1+2+..+100
/* 第一种方法 */
awk 'BEGIN{sum=0;i=1;while(i<=100){sum+=i;i++}{print sum}}'
/* 第二种 */
echo {1..100}|awk -F"+" awk'{sum=0;i=1;while(i<=100){sum+=i;i++;}{print sum}}'
计算平均成绩(先准备号文件并先筛选出需要的列)
/* 四个参数 */
awk '!/^name/{if($3=="m"){score_m+=$2;num_m++}else if($3=="f"){score_f+=$2;num_f++}}END{print "av_m="score_m/num_m,"av_f="score_f/num_f}' ./score.txt
/* 两个参数 */
awk '!(NR==1){score[$3]+=$2;num[$3]++}END{for(sex in num){if(sex=="m"){print "av_m="score[sex]/num[sex]}else if(sex=="f"){print "av_f="score[sex]/num[sex]}}}' ./score.txt
awk 'NR!=1{score[$3]+=$2;num[$3]++}END{for(sex in num){print sex":av="score[sex]/num[sex]}}' ./score.txt
统计/etc/fstab文件中每个单词出现的次数
awk '{for(i=1;i<=NF;i++)word[$i]++}END{for(i in word){print word[i],i}}' /etc/fstab
AWK
- grep过滤文件
- sed不光可以过滤,还可以写正则表达式修改文件
- awk能格式化文本输出,让结果按着我们定义的语法格式输出
GNU awk(gawk)
- 基本用法
- awk [options] ‘program’ var=value file…,这里program是awk自己的格式
- awk [options] -f programfile var=value file…,也可以把内容写到文件中,再调用文件
- awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file ...
- awk 程序通常由:BEGIN语句块、能够使用模式匹配的通用语句块、 END语句块,共3部分组成
- program被单/双引号引中,一般用单引号,program中的分隔符可以用双引号
- 选项
- -F 指明输入时用到的字段分隔符
- -v var=value: 自定义变量
awk语言
- awk [options] 'program' file…
- program:pattern{action statements;..}
- pattern和action
- pattern部分决定动作语句何时触发及触发事件
- action statements对数据进行处理,放在{}内指明
- 分割符、域和记录
- 与shell中的$符号意义不同,awk执行时,由分隔符分隔的字段(域)标记$1,$2..$n称为域标识。 $0为所有域
- 文件的每一行称为记录
- 省略action,则默认执行 print $0 的操作
- 默认分隔符是空格
awk工作原理
- 第一步:执行BEGIN{action;… }语句块中的语句
- 第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action;… }语句块,它 逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。</