AWK:Aho Weinberger Kernighan

awk :报告生成器、格式化文本输出

一、gawk - pattern scanning and processing language

  基本用法:gawk [optins] 'program' FILE ...

    语句之间用分号分割
  选项
    -F ' ' :指明输入时用到的字段分隔符
    -v var=value :自定义变量
  PATTERN: 定义读入哪些行时对行处理
  ACTION :对行如何处理,文本格式化输出:print, printf 多个语句之间用“;”分开

二、工作模式:

  默认读取全文 ,PATTERN只是决定能处理的行,同sed

  读取文件一行,以-F指定的输入字段分隔符切割字段,并且将每一片记录与awk内建的变量中,$1,$2,$3,...$#,$@,$0 ,支持行的字段条件判断,判断后此行满足时,显示此行的部分字段或对行内循环

注:默认以空格分隔,不管空白字符多少都只认为一个空白字符

三、变量

3.1、内建变量

a)FS:input field seperator 默认为空白字符    

 e.g      awk '{print $1}' /etc/passwd  

        awk -v FS=":"  '{print $1,$3}' /etc/passwd

b)、OFS :output field seperator 默认为空白字符

    

c) 、RS:Raw Seperator   输入的换行符,默认为$

d)、ORS:Output Raw Seperator   输出时的换行符,默认为$   

    awk -v RS=":" -v  ORS="^_^" '{print $1,$3}' /etc/passwd

e)、NF :Number  of Raw 字段数量

  $NF:每行最后一个字段 

[root@redhat wilsontest]# awk '{print NF,NR,$0}END{print FILENAME}' filetest
hello wilson
world
linux
oracle
C++ 说明:
第一列NF输出读取记录的域的个数;
NR表示已经读取的记录数;
$0实际就是把记录输出出来; $0就表示一个记录,$1表示记录中的第一个字段。
一般 print $ 就是打印整行内容($0前面不需要反斜杠),print $1表示只打印每行第一个字段。

f)、NR :Number of Filed   文件中的行数

    #awk '{print NR}' FILE

  #awk '{print NR}' FILE1   FILE2 ...  对行进行累计计数

g)、FNR :对每一个文件单独计数

   #awk '{print FNR}' FILE1 FILE2 ...   对每个文件分别计行数

h)、FILENAME:显示当前被处理的文件的文件名

  #awk '{print  FILENAME}' FILE1  FILE2

I)、ARGC : 命令行中给定的参数的个数

   #awk  '{print  ARGC}'  FILE1  FILE2

K)、ARGV :数组,保存的是命令行所给定的各参数

 

e.g

  awk '{print ARGV[0]}' /etc/fstab /etc/issue =====》awk
  awk '{print ARGV[1]}' /etc/fstab /etc/issue ======》/etc/fstab
  awk '{print ARGV[2]}' /etc/fstab /etc/issue ======》/etc/issue

 

3.2、自定义变量

a) -v name="Obama"
  变量名一样区分字符大小写

b) 在program中直接定义
  {name="value";print name}
  注:变量不能用$符,$符号表示字段
    变量用能用"" ,""中的变量不会被替换

四、ACTION

4.1、print -----输出内容之后自动换行

print  item1,item2,...

  要点:
    a) 逗号分隔符
    b) 默认输出分隔符为空白字符
    c) 输出的各item可以字符串,也可以是数值;当前记录的字段、变量或awk的表达式
     字符串 :"STRING"
     变量: 不能被引号包含
     即放在引号之内当做字符串,放在引号之外才能做变量替换
    d) 如省略item ,相当于{print} ==》 {print $}

  

 4.2、printf-----可以自定义输出的模式,另外输出内容之后不自动换行

  文本格式化输出:printf "FORMAT" ,item1,item2, ...

  a)FORMAT是必须要输出

  b) 不会自动换行,需要给出换行控制符:\n

  b)format中需要分别为后面的每个item指定一个格式化符号

格式符:

%c  : 显示字符的ASCII码

%d, %i :显示为十进制整数

%e :科学计数法 数值显示

%f : 显示为浮点数

%g,%G :以科学计数法或浮点形式显示数值

%s : 显示字符串

%u :无符号整数

%% :显示%自身

修饰符 :

#[.#] :第一数字控制显示的宽度;第二个#表示小数点后的精度

- :左对齐。默认为右对齐

+ : 显示数值的符号

e.g

 awk -F : '{printf "%s,%d\n",$1,$2}' /etc/passwd

 awk -F : '{printf "%-15s,%d\n",$1,$3}' /etc/passwd

 

  awk -F : '{printf "Username:%-15s UID:%d\n",$1,$3}' /etc/passwd

3、操作符

函数调用:函数名(argu1,argu2,...)

  function_name(arg1,arg2,...)   规范式

内建条件表达式:

  selector?if-ture-expression:if-false-expression

     selector :条件表达式

      ?:看它为真或假

      if-ture-expression :条件表达式为真时,执行

      if-false-expression :条件表达式为假时,执行

   

awk -F: '{$3>=1000?usertyep="Common User":usertype="Sysadmin or SysUser";printf "%15s:%s\n",$1,usertype}' /etc/passwd

五、PATTERN地址定界功能 :'PATTERN{ACTION STATEMENT}'

5.1、empty :处理文本的每一行,sed空模式,每一行都会进行script

5.2、/regex-pattern/ 仅处理能够被此处的模式所匹配到的行

   #awk  '/^UUID/{print $1}' /etc/paawd

 5.3、relational expression : 关系表达式,结果有“真”有“假”  ---结果为“真”才会被处理

     真:结果为非0值,非空字符串

       0表示假;空串为假

   #awk  -F ':'  ‘$3>=1000{print $1,$2}’   /etc/passwd    显示用户id大于1000的用户名

   #awk  -F ':'  '$NF=="/bin/bash" {print $1,$NF}’   /etc/passwd

5.4、模式符号 (所制定要匹配的字符要用 “//” 圈起来)

  显示用户shell为bash

    #awk  -F ':'  '$NF~/bash$/ {print $1,$NF}’   /etc/passwd

5.5、地址定界 

line ranges :行范围

  #awk  -F ':'  '(NR >=10 && NR<=20) {print $1}’   /etc/passwd

/PATTERN/,/PATTERN/ :第一个指定的模式匹配开始 ---另一个指定模式匹配结束

  #awk  -F ':'  '/^root/,/^myuser/ {print $1}’   /etc/passwd

注:不支持直接给出数字的格式

5.6、BEGIN/END模式  即表头/表尾

  BEGIN{program} :{}里面为代码段 仅在开始处理文件中每一行文本之前,仅执行一次;(表头)

  END{program}  仅在文本处理完成后,命令结束前仅执行一次; (表尾)

 awk -F ":" 'BEGIN{print "username     uid \n================"}{print $1,$3}' /etc/passwd 

  awk -F ":" '{print "username uid \n================" ;print $1,$3}' /etc/passwd   #每一行都会显示

5.7、! 取反

六、ACTION

6.1 if-else 

使用场景:对awk取得的整行或某个字段做条件判断

语法:
{if (condition) {true-statement}} 或 if (condition) true-statement
{ if (condition) {true-statement} else {false-statement} }
e.g
id号大于1000为普通用户
# awk -F ':' '{if ($3>500){print $1,$3}}' /etc/passwd
# awk -F ':' '{if ($3>500){printf "%15s %-d\n",$1,$3}}' /etc/passwd

awk -F: '{if($3>1000){printf "Common user:%s\n",$1} else {printf "Root or System:%s\n",$1}}' /etc/passwd

最后一个字段的行/bin/bash结尾
# awk -F ':' '{if ($NF == "/bin/bash"){print $1,$3}}' /etc/passwd
# awk -F ':' '{if ($NF ~ /\<bash$/){print $NF}}' /etc/passwd
每行字段数大于5个,显示行,否则不显示
# awk -F ':' '{if (NF>5){print $0}}' /etc/passwd
显示文件系统使用结果>80则显示

 df -h|awk -F "%" '/^\/dev/{print $1}'|awk '{if($NF>20){print $1}}'   条件过滤

# df -hP | awk -v FS="%" '!/^File/{print $1}' | awk '{if ($NF>80){print $1}}'

6.2、while  

使用场景:对一行内的多个字段逐一处理时使用;对数组中各元素逐一处理时使用

while (condition) {true-statement}
(condition) 判断条件
{true-statement} 条件为真时,执行循环体 length(arg1,arg2,...) 显示字段的长度

a)对整个一行中的各字段,显示各字段内容和字段中包含的字段的个数

思路: awk '{print length($i)}' FILE
i表示每个字段即可
#awk '/^[[:space:]]*linux16/{i=1;while(i<NF) {print $i,length($i);i++ }}' /tmp/grub2.cfg
linux16
/boot/vmlinuz-3.10.-957.27..el7.x86_64
root=UUID=eb448abb--4d8d-bcde-94434d586a31
ro
crashkernel=auto
net.ifnames=
idle=halt

b)循环嵌套if条件判断

对整个一行中的各字段,字段大于等于7才显示字段内容和字段中包含的字段的个数

#awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)};i++}}' ./grub2.cfg
linux16

6.3、do-while循环

do {true-statement} while (condition)
意义:至少执行一次循环体
# awk '{i=1;do {print $i,length($i);i++} while (i<=NF)}' /etc/issue

6.4   for 循环

for (控制变量初始化;控制变量条件表达式;控制变量的修正表达式) {statement}
for (variable assignment;condition;iteration process) {for-body}

#awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' ./grub2.cfg
linux16 7

#awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {if(length($i)>=16) print $i,length($i)}}' ./grub2.cfg
/boot/vmlinuz-3.10.0-957.27.2.el7.x86_64 40

注:循环体中嵌套单分支if语句 ,单分支if的statement的{} 可省略

特殊用法:能够遍历数组中的元素

  语法:for(var in array) {for-body}

6.5switch语句 多分支if

字符串比较使用(awk 不常用)

switch (expression) (case VALUE1 or /REGEXP1/:statement;case VALUE2 or /REGEXP2/:statement;...; default:statemet)
表达式 == value1 或 表达式 ~ /REGEXP1
default:statemet ==相当于bash语句case中 最后*)statemet;

6.6 break [n] 或 continue---提前结束本轮循环直接进入下一个循环(无非处理的时下一个字段而已)

显示奇数字段
# awk -F ':' '{i=1;while (i<=NF){if (i%2==0) {i++;continue} else {print i,$i;i++}}}' /etc/passwd

6.7 next(控制awk内生循环)-----提前结束对本行的处理直接进入下一行

显示以/bin/bash结尾的行,非/bin/bash结尾的行next
# awk -F ':' '{if ($NF != "/bin/bash"){next} else {print $0}}' /etc/passwd
显示用户id号为偶数的用户
# awk -F ':' '{if ($3%2 != 0){next} else {print $0}}' /etc/passwd

6.8 、array数组

关联数组:array_name[index-expression]

    index-expression(索引表达式)
       可使用任意字符串:字符串要使用双引号
       如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”
       内部的字符串,必须要用到双引号,变量不能使用'"" 若要判断数组中是否存在某元素,要使用“index in array”格式进行 赋值 weekdays["mon"]="Monday" 显示 print weekdays["mon"]
e.g 显示第一个元素
# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Thuseday";print weekdays["mon"]}'

遍历数组每个元素要使用for循环

语法:for (var in array) {statement}

    var会遍历数组array[Index]的每个索引(下标index)
      var会逐一被赋值,为array的每一个Index
# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Thuseday";for(i in weekdays) {print weekdays[i]}}'

场景:当多类数值,统计每一类数值各自出现多少次

netstat -ant | awk '/^tcp\>/'    # ^ 行开头; \> 单词结尾
1)查看所有状态
netstat -tan | awk '{print $NF}' )# netstat -tan | awk '/^tcp\>/'{state[$NF]++} END{for (i in state){print i,state[i]}}'
统计日志

)查看httpd是否被安装
rpm -q httpd
) 启动httpd
service httpd start
)httpd自带压力测试工具,ab
ab -c -n
)统计日志IP
# awk '{count[$1]++}END{for (i in count){print i,count[i]}}' /var/log/httpd/access_log
统计/etc/fstab文件中每个单词出现的次数(行内字段遍历)
# awk '{i=1;while (i<=NF){count[$i]++;i++}}END{for (i in count){print i,count[i]}}' /etc/fstab
# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for (i in count){print i,count[i]}}' /etc/fstab
统计/etc/fstab文件中每个文件系统类型出现的次数
# awk '{print $3}' /etc/fstab
# awk '/^UUID/{fs[$3]++}END{for (i in fs){print i,fs[i]}}' /etc/fstab

6.9、函数(了解)

a)、内置函数

  1)、数值处理:

    rand():返回0和1之间的一个随机数

     #awk 'BEGIN{print rand()}'

注:awk命令取随机时只要取得一次后,以后这个随机数字永远为第一次取得的随机数值

  2)、字符串处理:

    length([s]) :返回指定字符串的长度

    sub(r,s,[t]):[t] 可选参数

        以r表示的模式,来查找t所表示的字符中的匹配的内容,并将其第一次出现替换为s所表示的内容

        # awk -F ':' '{sub("o","O",$1);print}' /etc/passwd

   gsub(r,s,[t]):[t] 可选参数

     以r表示的模式,来查找t所表示的字符中的匹配的内容,并将其所有匹配到的内容替换为s所表示的内容

  split(s,a[,r])

     以r分割符切割字符串s,将切割后的结果保存至a所表示的数组中

统计每一个ip建立ip的个数

# netstat -tan|awk '/^tcp\>/{split($5,ip,":");print ip[1]}'
0.0.0.0
0.0.0.0
116.77.75.251
100.100.30.26

  # netstat -tan|awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count){print i,count[i]}}'
  116.77.75.251 1
  0.0.0.0 2
  100.100.30.26 1

 
统计每一个ip建立ip的个数
# netstat -tnl | awk '!/^Proto/ && !/^Active/{split($5,state,":");ip[state[1]]++}END{for (i in ip){print i,ip[i]}}'

https://www.cnblogs.com/sky-k/p/9435611.html

三十一、Gawk基础入门的更多相关文章

  1. 小白学 Python 爬虫(4):前置准备(三)Docker基础入门

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  2. ElasticSearch7.3学习(三十一)----Logstash基础学习

    一.Logstash基本介绍 Logstash 是一个功能强大的工具,可与各种部署集成. 它提供了大量插件,可帮助你解析,丰富,转换和缓冲来自各种来源的数据(文件.数据库......).logstas ...

  3. ELKStack的基础入门和中文指南

    一.ELKStack的中文指南 redhat系列配置repo源 rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch vi / ...

  4. 小白学 Python 爬虫(32):异步请求库 AIOHTTP 基础入门

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  5. Membership三步曲之入门篇 - Membership基础示例

    Membership 三步曲之入门篇 - Membership基础示例 Membership三步曲之入门篇 -  Membership基础示例 Membership三步曲之进阶篇 -  深入剖析Pro ...

  6. Bootstrap <基础三十一>插件概览

    在前面布局组件中所讨论到的组件仅仅是个开始.Bootstrap 自带 12 种 jQuery 插件,扩展了功能,可以给站点添加更多的互动.即使不是一名高级的 JavaScript 开发人员,也可以着手 ...

  7. [转]Membership三步曲之入门篇 - Membership基础示例

    本文转自:http://www.cnblogs.com/jesse2013/p/membership.html Membership三步曲之入门篇 - Membership基础示例   Members ...

  8. Swift语法基础入门三(函数, 闭包)

    Swift语法基础入门三(函数, 闭包) 函数: 函数是用来完成特定任务的独立的代码块.你给一个函数起一个合适的名字,用来标识函数做什么,并且当函数需要执行的时候,这个名字会被用于“调用”函数 格式: ...

  9. PHP基础入门(三)---PHP函数基础

    PHP基础入门(三)---函数 今天来给大家分享一下PHP的函数基础.有了前两章的了解,想必大家对PHP有了一定的基础了解.想回顾前两章的朋友可以点击"PHP基础入门(一)"&qu ...

随机推荐

  1. hdu 1075 map的使用 字符串截取的常用手段 以及string getline 使用起来的注意事项

    首先说字符串的截取套路吧 用坐标一个一个的输入 用遍历的方式逐个去检查字符串中的字符是否为符合的情况 如果是的话 把该字符放入截取string 中 让后坐标前移 如果不是的话 截取结束 坐标初始化 然 ...

  2. 每周分享五个 PyCharm 使用技巧(三)

    文章首发于 微信公众号:Python编程时光 PyCharm 是大多数 Python 开发者的首选 IDE,每天我们都在上面敲着熟悉的代码,写出一个又一个奇妙的功能. 一个每天都在使用的工具,如果能掌 ...

  3. 使用 rm -rf 删除了工程目录,然后从 pycharm 中找了回来

    一次惊险的 rm -rf 操作,以后删东西真的要小心,慢点操作 前两天周 4 周 5,写了两天的 python 代码没有提交,昨天晚上删日志目录,先跨目录查看了下日志目录的列表情况:ll ~/logs ...

  4. 自定义标签之inclusion_tag

    1.在当前app下创建templatetags文件夹 2.在templatetags文件夹下面创建自定义的mytag.py文件 3.在mytag.py文件中的代码 from django.templa ...

  5. 可以在一个.java文件中写两个类吗?

    一个java文件中可以有任意多个类,接口或是注解..但是只能有一个类是public的,而且这个类的名字要和文件同名,比如public类名为A则文件名就应当为A.java

  6. Java 之 序列化流

    一.序列化概述 Java 提供了一种对象 序列化 的机制.用一个字节序列可以表示一个对象,该字节序列包含该 对象的数据 . 对象的类型 和 对象中存储的属性 等信息.字节序列写出到文件之后,相当于文件 ...

  7. iOS 如何判断一个点在某个指定区域中

    在iOS 开发中会遇到 判断位置的情况 iOS 自己都有函数实现的这些功能. 判断一个点是否在这个rect区域中 bool CGRectContainsPoint(CGRect rect,CGPoin ...

  8. 文件锁 flock/fcntl

    多个进程同时操作一个文件 1. flock int flock(int fd, int operation); LOCK_SH 建立共享锁定.多个进程可同时对同一个文件作共享锁定(读锁定) LOCK_ ...

  9. 服务发现之consul理论整理_结合Docker+nginx+Tomcat简单部署案例

    目录 一.理论概述 服务发现的概念简述 consul简述 二.部署docker+consul+Nginx案例 环境 部署 三.测试 四.总结 一.理论概述 服务发现的概念简述 在以前使用的是,N台机器 ...

  10. java - day016 - IO续(输入输出), 手写双向链表

    课程回顾 对象的创建过程 类加载 加载父类,父类的静态变量分配内存 加载子类,子类的静态变量分配内存 父类静态变量赋值运算, 和静态初始化块 子类静态变量赋值运算, 和子类初始化块 创建对象 创建父类 ...