awk的介绍和使用

1 awk的介绍

awk: Aho,Weinberger,Kernighan,报告生成器.格式化输出
grep: 文本过滤 egrep pattern
sed: 行编辑器 模式空间 保持空间
基本用法
  gawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
  gawk [ POSIX or GNU style options ] [ -- ] program-text file ...
  awk 程序通常使用:BEGIN语句块,能使用模式空间匹配的通用块,END语句块,共三部分组成
  program 通常使用单引号
  基本格式:awk [options] 'program' file…
  program:pattern{action statements;..}
  pattern 和action: :
    pattern 部分决定动作语句何时触发及触发事件
  BEGIN,END
    action statements 对数据进行处理,放在{} 内指明
    print, printf
  分割符、域和记录
    awk 执行时, 由 分隔符分隔的字段(域)标记$1,$2..$n称 称为域标识。$0 为所有域,注意:和shell 中变量$ 符含义不同
    文件的每一行称为记录
    省略action行 ,则默认执行 print $0 的 的 操作  
print格式: print item1,item2 ...
要点:
  1 逗号分隔
  2 输出的各item可以字符串,也可以是数值,当前记录的字段,变量或awk的表达式
  3 如果省略item 相当于print $0
示例:
  1 awk '{print "hello"}'
  [root@test5(172.18.254.5) ~]#awk '{print "hello,world,awk" }'
  a
  hello,world,awk
  b
  hello,world,awk
  2  awk -F: '{print $0}' /etc/passwd
  [root@test5(172.18.254.5) ~]#awk -F: -v ORS=' ' '{print $1}' /etc/passwd
  root bin daemon adm lp sync shutdown halt mail uucp operator games gopher ftp nobody dbus vcsa abrt haldaemon ntp sasl
auth postfix sshd tcpdump
  # 指明输出使用的记录分隔符

2 awk 的变量 需要使用 -v 指定

FS: 输入字段分隔符,默认为空白字符
OFS: 输出字段分隔符,默认为空白字符
RS: 输入记录分隔符,指定输入时的换行符,原换行符仍有效
ORS: 输出记录分隔符,输出时用指定符号代替换行符
NF: 字段数量
NR: 行号,如果是多个文件,将一起计数
FNR: 行号,如果是多个文件,将分别计数
FILENAME: 当前参数文件名
ARGV: 命令行参数的个数
ARGV:数组,保存的是命令行所指定的各参数
  [root@test5(172.18.254.5) ~]#awk 'BEGIN{print   ARGV[0],ARGV[1],ARGV[2]}' /etc/passwd /etc/issue
  awk /etc/passwd /etc/issue
# 用户自定义的变量
  awk –F: '{sex="male";print $1,sex,age;age=18}' /etc/passwd
printf命令 当使用printf的时候 print的变量有时候不起作用
格式化输出:printf  “FORMAT ”, item1, item2, ...
  (1)  必须指定FORMAT
  (2)  不会自动换行,需要显式给出换行控制符,\n
  (3) FORMAT 中需要分别为后面每个item 指定格式符
格式符:与item 一一对应
  %c:  显示字符的ASCII码 码
  %d, %i:  显示十进制整数
  %e, %E: 显示科学计数法数值
  %f :显示为浮点数
  %g, %G :以科学计数法或浮点形式显示数值
  %s :显示字符串
  %u :无符号整数
  %%:  显示% 自身
修饰符:
  #[.#]:第一个数字控制显示的宽度;第二个# 表示小数点后精度,%3.1f
  -: 左对齐(默认右对齐) %-15s
  +: 显示数值的正负符号 %+d
将数字对应的ascii打印出来
  [root@test5(172.18.254.5) ~]#cat test.txt
  88 89 90
  [root@test5(172.18.254.5) ~]#awk '{i=1;while(i<=NF){printf "%c\n",$i;i++}}' test.txt 
  X
  Y
  Z
将ascii对应的数字打印出来
  [root@test5(172.18.254.5) ~]#for i in {a..z};do printf "%d " "'$i";done
  97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 
获取磁盘利用率
  df -P | awk -F"[% ]"  '/\/dev/&& $(NF-2) >= 10{print $1,$(NF-2)}'
awk的一些定义
  awk 'BEGIN{i=0;print i++,i}'  1  1  i=i++ 
  awk 'BEGIN{i=0;print ++i,i}'  0  1  i=++i
awk '{i=1;sum=0;while(i<=NF){sum+=$i;i++};print sum,i}' /file.txt 
 # 可以将 每行计算一个数字
awk '{i=1;while(i<=NF){sum+=$i;i++};print sum,i}' /file.txt
# 可以将 每行中的数加在一起   统计出来一个数字
pattern 类似 sed 的定界符
1 empty:空模式 匹配任一行
2 /regular expression/:仅处理被pattern匹配到的行
3 relational expression :关系表达式 结果 有真 有假 结果为真 才会被处理 假 过滤
  真 结果为非零 非空串;
  awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd
  awk -F: '$NF="/bin/bash"{print $1,$NF}' /etc/passwd
4 line range 行范围
  tartline endline  /pat1/,/pat2/
  awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
5 BEGIN/END 模式
  BEGIN():仅在开始处理文件中的文本之前执行一次  在未执行pattern中执行之前,执行END() 仅在文本处理完成之后执行一次
  awk -F: 'BEGIN{print "  USERNAME          uid   \n"}{printf "%-20s%3s\n",$1,$3}END{print "***************************\n          end"}' /etc/passwd

3 控制语句

if (condition) {statements}
if (condition) {statements} else {statements}
do {statements} while(condition)
for (expr;expr2;expr3){statements}
break
continue
delete array[index]
delete array
exit
{ statements }
1 if-else
  语法 if(condition) statement [else statement]
    awk -F: '{if($NF~/bash$/) print $1,$NF}' /etc/passwd
    awk -F: '{if($3>1000) {printf "common user:%s\n",$1} else {printf "root or sysuser:%s\n",$1}}' /etc/passwd
    awk '{if(NF>7) print $0}' /etc/fstab
df -hP | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>30) print $1}'
    使用场景:对awk取得的整行或某个字段做条件判断
2  while
  语法 while (condition) statement
    条件为真 进入循环 条件为假 退出循环
    使用场景 对一行内的多个字段逐一做类似处理时使用,对数组中的各元素逐一处理使用
    awk '/^[[:space:]]+linux16/{i=1;while(i<NF){print $i,length($i);i++}}' /etc/grub2.cfg
    awk '/^[[:space:]]+linux16/{i=1;while(i<NF){if(length($i)>=7) print $i,length($i);i++}}' /etc/grub2.cfg 
3 do..while
   语法 do statement while(condition)
    意义 至少运行一次
4 for 循环
  语法 for(expr1;expr2;expr3) statement
    特殊用法
      能够遍历数组中的元素
      语法 for(var in array){for body}
5 switch 语句
  语法:switch(expression) {case value or /pat/: statement;case value2 or /pat2/: statement;...default:statement}
6 break和continue
  break [n] 退出几层循环
  continue 退出当前循环
7 next 控制awk 的内生循环
  提前结束对本行的处理而直接进入下一行
    awk -F: '{if($3%2!=0) next;print $1,$3}' /etc/passwd

4 数组

关联数组 array[index-expression]
  index-expression 
    1 可使用任意字符串 字符串要是用双引号
    2 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其初始化为空串要判断数组中是否存在某元素,要是用index in array 格式进行
  去除重复的行
    awk -F":" '!a[$7]++' /etc/passwd
  显示行重复的次数
    awk -F":" '{!a[$0]++;print $0,a[$0]}' test.txt          
  若要遍历数组中的每一个元素,要是用for 循环
    for(var in array) statement
    awk 'BEGIN{weekends["mon"]="Monday";weekends["tue"]="Tuesday";for(i in weekends){print weekends[i]}}'
    注意 var 会遍历array 的每一个索引
    netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state){print i,state[i]}}'
    netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state){print i,state[i]}}'
练习
    统计/etc/fstab 文件中每个单词出现的次数
awk '{i=1;while(i<=NF){danci[$i]++;i++}}END{for(i in danci){print i,danci[i]}}' /etc/fstab
    统计/etc/fstab文件中 文件系统的类型及个数
awk '/^\/dev|^UUID/{type[$3]++}END{for(i in type){print i,type[i]}}' /etc/fstab

5 内置函数

数值处理
  rand();返回0和1之间的随机数 只有第一次使用时随机的,(不做特殊处理)以后都会相同的
  需要生成一个种子 srand()
    awk 'BEGIN{srand();for(i=1;i<=10;i++)printf "%d ",rand()*100}'
    awk 'BEGIN{srand();print rand()}'
    awk 'BEGIN{srand();printf "%d",rand()*100 }'
    awk 'BEGIN{srand();print int(rand()*100) }'
字符串处理
  length([s]) 返回字符串长度
  sub(r,s[t])以r表示的模式来查找t所代表的字符串中的匹配的内容,并将其第一次出现替换为s所代表的内容
    echo "2008:08:08 08:08:08" |awk 'sub(/:/,"-",$1)'
    2008-08:08
  gsub(r,s[t])以r表示的模式来查找t所代表的字符串中的匹配的内容,并  将所有出现均替换为s所代表的内容
    echo "2008:08:08 08:08:08" |awk 'gsub(/:/,"-",$1)'
    2008-08:08
  split(s,a[,r]):以r为分隔符切割s字符,并将切割后的结果保存至a所表示的数组当中下标从1开始
    netstat -tan | awk '/^tcp\>/{split($5,ip,":");print ip[1]}'
    netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}'
练习
1 、统计/etc/fstab 文件中每个文件系统类型出现的次数
  awk '!/^#/&&!/^$/{type[$3]++}END{for(i in type){print i,type[i]}}' /etc/fstab
  awk '/^[^#]/{type[$3]++}END{for(i in type){print i,type[i]}}' /etc/fstab
2 、统计/etc/fstab 文件中每个单词出现的次数
  awk '{i=1;while(i<=NF){danci[$i]++;i++}}END{for(i in danci){print i,danci[i]}}' /etc/fstab
3 、提取出字符串Yd$C@M05MB%9&Bdh7dq+YVixp3vpw中 中的所有数字
  echo 'Yd$C@M05MB%9&Bdh7dq+YVixp3vpw' | awk -v FS="[^0-9]+"    '{i=1;while(i<=NF){{if($i ~ "[0-9]+")print $i};i++}}'
4 、解决DOS 攻击生产案例:根据web 日志或者或者网络连接数,监控当某个IP 并发连接数或者短时内PV 达到100 ,即调用防火墙命令封掉对应的IP ,监控频率每隔5 分钟。防火墙命令为:iptables -A INPUT -s IP -j REJECT
#!/bash
declare -a dos
while :;do
dos=(`awk '{ip[$1]++}END{for(i in ip){if(ip[i]>100)print i}}' test.txt`)
    for i in ${dos[@]};do
        iptables -A INPUT -s $i -j REJECT
    done
sleep 300
done
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容

  • 转载 原文的排版和内容都更加友好,并且详细,我只是在这里贴出了一部分留作自己以后参考和学习,如希望更详细了解AWK...
    XKirk阅读 3,196评论 2 25
  • awk介绍awk变量printf命令:实现格式化输出操作符awk patternawk actionawk数组aw...
    哈喽别样阅读 1,560评论 0 4
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,149评论 2 34
  • awk: grep,sed,awk grep:文本过滤 sed:文本编辑 awk:文本格式化工具; 1 什么是aw...
    木林森阅读 1,769评论 0 16
  • 初雪见花开 独品寒意来 原欢滴露喜眉梢 不轻扰 姿态俏 风雪夜过落孤傲 赛江南妖娆 翘首以盼 冬季寒窗 移香别恋花...
    小毛毛雨阅读 186评论 2 0