• Linux文本三剑客之首——awk


    内容预知

     1.awk相关知识

    1.1 awk的相关介绍 

    1.2 awk的工作原理 

    1.3 awk的数学计算(浮点运算)

     2.awk的基础用法和选项

     2.1 awk的基本格式及其内置变量

    2.2 基本打印用法

     2.2.1 打印文章所有内容

    ​编辑 

    2.2.2 打印行内容及其行号

     2.2.3 指定行和指定行范围打印

    2.2.4 奇偶行打印

     2.2.5 奇偶打印特殊方式的引入——getline

    2.2.6 文本内容匹配过滤打印 

    2.3 BEGIN打印模式 

     2.4 对字段进行处理打印

     2.4.1 指定分隔符打印字段

    2.4.2 条件判断打印

     3. awk的三元表达式与精准筛选用法

    3.1 awk的三元表达式

     3.1.1 Java和shell的三元表达式

    3.1.2 awk的三元表达式运用 

    3.2 awk的精准筛选

    4.awk的分隔符用法

    4.1  RS 指定行分隔符

    4.2 指定输出的分隔符 

    4.2.1 tr改变分隔符输出

    4.2.2 awk改变输出分隔符

     5. awk结合数组运用

     5.1 awk中定义数组打印

     5.2 awk打印文件内容去重统计

     5.2.1 去重打印数组

     5.2.2 处理文件去重统计

     实例引用

     6. 常用awk筛选数据实例

     6.1  获取本机上一次开机时间

     6.2 获取本机IP地址

     6.3  检测本机cpu 15分钟内的平均负载

     6.4 检测入站网卡流量和出站网卡的流量

    6.5 内存剩余量

    6.6 根分区剩余量

     其他有用数据的提取(非awk)

     总结


     1.awk相关知识

    1.1 awk的相关介绍 

     

    AWK是一种优良的文本处理工具。它不仅是 Linux中也是任何环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母)的最大功能取决于一个人所拥有的知识。AWK 提供了极其强大的功能:可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上 AWK 的确拥有自己的语言:AWK 程序设计语言, 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。 

     Linux中最常用的文本处理工具有grep,sed,awk。行内将之称为文本三剑客,就功能量和效率来看,awk是当之无愧的文本三剑客之首

     

     

    1.2 awk的工作原理 

     

    逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。

    通常awk是将一行数据拆分为多个字段,操作者,可以选取指定的字段对其进行高效率的操作

     

    1.3 awk的数学计算(浮点运算)

    具体使用方法,在本人前面的博客有记录: 

    shell脚本的编写规范和变量类型_站在这别动,我去给你买橘子的博客-CSDN博客icon-default.png?t=M85Bhttps://blog.csdn.net/qq_62462797/article/details/126489020?spm=1001.2014.3001.5501

     2.awk的基础用法和选项

     2.1 awk的基本格式及其内置变量

     awk 选项 '模式或条件 {操作}' 文件1 文件2...

     ​awk -f 脚本文件 文件1 文件2

     

    • 注意一定是单引号:'模式或条件 {操作}'
    • { }外指定条件,{ }内指定操作。
    • 用逗号指定连续的行,用 || 指定不连续的行。&&表示”且“。
    • 内建变量,不能用双引号括起来,不然系统会把它当成字符串。

     

    内置变量作用
    $0当前处理的行的整行内容
    $n当前处理行的第n个字段(第n列)
    NR当前处理的行的行号(序数)
    NF当前处理的行的字段个数。$NF代表最后一个字段
    FS列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与"-F"作用相同
    OFS输出内容的列分隔符
    FILENAME被处理的文件名
    RS
    行分隔符。awk从文件中读取资料时,将根据RS的定义把资料切割成许多条记录, 而awk一次仅读入一条记录进行处理。预设值是"\n"

    2.2 基本打印用法

     

     2.2.1 打印文章所有内容

    [root@localhost awk]#awk '{print}' english.txt 
    

     

    另外:0和1放置{ }前,能够起到限制答应的作用(默认为"1")

     

     

     

    [root@localhost awk]#awk '{print $0 }' english.txt 
    

     

     

    2.2.2 打印行内容及其行号

     

    [root@localhost awk]#awk '{print NR}' english.txt 
    

     

     

    [root@localhost awk]#awk '{print NR,$0}' english.txt

     

     2.2.3 指定行和指定行范围打印

     

    1. [root@localhost awk]#awk 'NR==3{print}' english.txt
    2. [root@localhost awk]#awk 'NR==3,NR==5{print}' english.txt
    3. [root@localhost awk]#awk '(NR>=3)&&(NR<=5){print}' english.txt

     

     

    2.2.4 奇偶行打印

    1. [root@localhost awk]#awk 'NR%2==0{print}' english.txt
    2. [root@localhost awk]#awk 'NR%2==1{print}' english.txt

     

     2.2.5 奇偶打印特殊方式的引入——getline

     

     getline的工作过程:

     (1)当getline左右无重定向符号(“<”)或者管道符号(“|”)时,awk首先读取的是第一行,而getline获取的是是光标跳转至下一行的内容(也就是第二行)。

    原因:getline运行之后awk会改变NF,NR,$0,FNR等内部变量,所以此时读取$0的行号不再为1,而是2

     

    拓展:

    FNR:awk当前读取的记录数,其变量值小于等于NR,(比如说当读取完第一个文件后,读取第二个文件,FNR是会从0开始进行,而NR不会)。因此读取两个或两个以上的文件,NR==FNR,可以 判断是不是在读取第一个文件

     

    (2)当getline左右有管道符号或重定向符时,getline则作用定向输入文件,由于文件是刚打开,并没有被awk读入一行,而只是getline读入,所以getline返回的是文件的第一行,而不是跳转至一行输入

    getline 打印偶数行: 

    1. [root@localhost awk]#awk '{getline;print $0}' english.txt
    2. [root@localhost awk]#seq 10|awk '{getline;print $0}'

     

     

    getline 打印奇数行 :

     

    1. [root@localhost awk]#awk '{print $0;getline}' english.txt
    2. [root@localhost awk]#seq 10|awk '{print $0;getline}'

     

    2.2.6 文本内容匹配过滤打印 

     

    1. [root@localhost awk]#awk '/^root/{print}' /etc/passwd
    2. [root@localhost awk]#awk '/bash$/{print}' /etc/passwd

     

     

    2.3 BEGIN打印模式 

     

     格式:awk 'BEGIN{...};{...};END{...}' 文件

     

     处理过程:


    1、在awk处理指定的文本之前,需要先执行BEGIN{...}模式里的命令操作

    2、中间的{...} 是真正用于处理文件的命令操作

    3、在awk处理完文件后才会执行END{...}模式里的命令操作。END{ }语句块中,往往会放入打印结果等语句。

     

    引例演示:
     

    [root@localhost awk]#awk 'BEGIN{x=1};{x++};END{print x}' english.txt 
    

     拓展提示:

     awk是从c语言中继承到Linux,所以在BEGIN模式中变量x,可以直接运用,无需"$"声明获取变量值

     

     2.4 对字段进行处理打印

     

     2.4.1 指定分隔符打印字段

     普通指定方式:

    1. [root@localhost awk]#head -n5 /etc/passwd |awk -F':' '{print$3}'
    2. [root@localhost awk]#head -n5 /etc/passwd |awk -F':' '{print$5}'

     

     BEIGIN模式指定:

     

    1. [root@localhost awk]#head -n5 /etc/passwd|awk 'BEGIN{FS=":"};{print $5}'
    2. [root@localhost awk]#head -n5 /etc/passwd|awk 'BEGIN{FS=":"};{print $3}'

     

    2.4.2 条件判断打印

     正向判断打印:

    [root@localhost awk]#awk -F: '$3>500{print $0}' /etc/passwd
    

     

     

    判断取反打印: 

    [root@localhost awk]#awk -F: '!($3>10){print $0}' /etc/passwd
    

     

     除此之外,甚至可以直接进行if语句判断打印:

     

    [root@localhost awk]#awk -F: '{if($3>500){print $0}}' /etc/passwd
    

     

     3. awk的三元表达式与精准筛选用法

    3.1 awk的三元表达式

     

     3.1.1 Java和shell的三元表达式

     

    java中: (条件表达式)?(A表达式或者值):(B表达式或者值)

     - 条件表达式成立(为真)时,会取冒号前面的值A。  - 条件表达式不成立(为假)时,会取冒号后面的值B。  

    ​  Shell中: [ 条件表达式 ] && A || B

     - 条件表达式成立(为真)时,会取||前面的值A。  - 条件表达式不成立(为假)时,会取||后面的值B。

    3.1.2 awk的三元表达式运用 

     

    awk的三元表达式继承了java的用法,格式与Java相似

     

    格式:awk     '(条件表达式)?(A表达式或者值):(B表达式或者值)'

     

    [root@localhost awk]# awk -F: '{max=($3>=$4)?$3:$4;{print max,$0}}' /etc/passwd|sed -n '1,6p'
    

     同时:通过管道符sed命令只打印其中的前六行内容

     

     

    3.2 awk的精准筛选

     

     精准筛选方法:

     $n(> < ==)  用于对比数值
    $n~"字符串" 代表第n个字段 包含 某个字符串的作用
    $n!~"字符串"代表第n个字段 不包含 某个字符串的作用
    $n=="字符串"代表第n个字段 为 某个字符串的作用
     $n!="字符串" 代表第n个字段 不为 某个字符串的作用
     $NF   代表最后一个字段

     

     

     运用1:输出第七个字段包含“bash”所在行的第一个字段和最后一个字段

    [root@localhost awk]#awk -F: '$7~"bash" {print $1,$NF}' /etc/passwd
    

     

      运用2:输出第七个字段不包含“nologin”所在行的第一个字段和最后一个字段

     

    [root@localhost awk]#awk -F: '$7!~"nologin" {print $1,$NF}' /etc/passwd
    

     运用3:指定第六个字段为/home/lisi   ,第七个字段为/bin/bash,输出满足这些条件所在行的第一个和最后一个字段

     

    [root@localhost awk]#awk -F: '($6=="/home/lisi")&&($7==/bin/bash)"nologin" {print $1,$NF}' /etc/passwd
    

     

    4.awk的分隔符用法

    4.1  RS 指定行分隔符

     awk从文件中读取资料时,将根据RS的定义把资料切割成许多条记录, 而awk一次仅读入一条记录进行处理。内置变量RS的预设值是"\n"。

     但是也可以在使用BEGIN模式在操作前进行行分隔符的改变

     

     

    [root@localhost awk]#echo $PATH|awk 'BEGIN{RS=":"};{print NR,$0}'
    

     

    4.2 指定输出的分隔符 

     

    FS 输入时的列分隔符。

    OFS 输出内容的列分隔符。($n=$n用于激活,否则不生效,n且必须存在)

     

     对于输出时改变分隔符,我们常用到tr,awk,它们都可以实现在输出内容改变原本的分隔符

    4.2.1 tr改变分隔符输出

     

    1. [root@localhost awk]#echo a b c d
    2. [root@localhost awk]#echo a b c d|tr " " ":"

     

     

    4.2.2 awk改变输出分隔符

     

    直接修改输出分隔符 :

    [root@localhost awk]#echo a b c d|awk '{OFS=":" ; $1=$1;print $0}'
    

    BEGIN模式中修改输出分隔符: 

    1. root@localhost awk]#echo a b c d|awk 'BEGIN{OFS=":"};{$2=$2;print $0}'
    2. [root@localhost awk]#echo a b c d|awk 'BEGIN{OFS=":"};{$3=$3;print $0}'
    3. [root@localhost awk]#echo a b c d|awk 'BEGIN{OFS=":"};{$4=$4;print $0}'
    4. [root@localhost awk]#echo a b c d|awk 'BEGIN{OFS=":"};{$5=$5;print $0}'

     

     5. awk结合数组运用

     5.1 awk中定义数组打印

     

    1. [root@localhost awk]#awk 'BEGIN{a[0]=10 ; a[1]=20 ; a[2]=30;print a[1]} '
    2. [root@localhost awk]#awk 'BEGIN{a[0]=10 ; a[1]=20 ; a[2]=30;print a[0]} '
    3. [root@localhost awk]#awk 'BEGIN{a[0]=10 ; a[1]=20 ; a[2]=30;print a[2]} '

     

    此外:awk中的数组还能形成遍历

    [root@localhost awk]#awk 'BEGIN{a[0]=10 ; a[1]=20 ; a[2]=30;for(i in a)print i,a[i]} '
    

     

     

     5.2 awk打印文件内容去重统计

     

     5.2.1 去重打印数组

     

    1. [root@localhost awk]#echo ${arry[@]}|awk -v RS=' ' '!a[$1]++'
    2. [root@localhost awk]#awk -v RS=' ' '!a[$1]++' <<< ${arry[@]}

     

     

     

     

     

     

     5.2.2 处理文件去重统计

    原理:将文件的字段内容变为定义的数组下标,对其进行匹配读取累加(只有遇到完全一致的才会累加),此时重复的次数在for循环的作用下成为了数组对应下标的元素,

    所以输出该下标和元素(就等同于输出重复的字段内容  以及 统计的重复次数)

     

    [root@localhost awk]#awk '{a[$1]++};END{for(i in a){print i,a[i]}}' test.txt
    

     

     实例引用

     

    需求: 

    统计ssh登录失败的用户及其登录失败(日志:/var/log/secure中有记录)的次数(通常我们会认为失败三次,存在着暴力破解登录的可能,意味该主机存在隐患)解决方案:将其筛选出来就把IP加入到黑名单中 /etc/hosts.deny。

    纯awk筛选统计: 

    [root@localhost awk]# awk '/Failed password/{a[$11]++};END{for(i in a){print i,a[i]}}' /var/log/secure
    

     其他awk组合方式:

    1. [root@localhost awk]#awk '/Failed password/{print $11}' /var/log/secure |sort -n
    2. [root@localhost awk]#awk '/Failed password/{print $11}' /var/log/secure |sort -n |uniq -c

     

     6. 常用awk筛选数据实例

    下面有很多的awk获取数据都可以配合脚本加计划性任务编写为一个全自动化运维的检测脚本 

     

     6.1  获取本机上一次开机时间

     

    [root@localhost awk]#date -d "$(awk -F. '{print $1}' /proc/uptime) second ago" +"%Y%m%d %H:%M:%S"
    

     

     6.2 获取本机IP地址

     

    [root@localhost awk]#ifconfig ens33|awk '/inet /{print $2}'
    

     

     

     

     6.3  检测本机cpu 15分钟内的平均负载

     

    一般超过百七十,就要注意了!!

     

    [root@localhost awk]#uptime|awk '{print $NF}'
    

     

     6.4 检测入站网卡流量和出站网卡的流量

    1. #入站网卡
    2. [root@localhost awk]#ifconfig ens33|awk '/RX p/{print $5}'
    3. #出站网卡
    4. [root@localhost awk]#ifconfig ens33|awk '/TX p/{print $5}'

     

     

    6.5 内存剩余量

     

    [root@localhost awk]#free -m |awk '/^Mem/{print $4}'
    

     

    6.6 根分区剩余量

     

    [root@localhost awk]#df -h|awk '/\/dev\/sda1/{print $4}'
    

     

     其他有用数据的提取(非awk)

     

     

     总结

     1. awk是一种对文件输出内容的字段(列),进行操作的工具,多数用来提取重要数据

    2. awk 结合数组时可以进行数组定义,数组遍历,以及数组元素的去重统计

    3.提取文件数据时,注意每行或列的分隔符,正确借用分隔符能够使提取的数据更加精确

  • 相关阅读:
    阿里巴巴中国站1688按关键词搜索商品api电商数据接口
    Ingress基本故障排除方法
    【Mysql专题】一条SQL在Mysql中是如何执行的
    ArrayList集合(干数组不能干的事)
    multiset 用法简说
    计算机毕设 大数据商城人流数据分析与可视化 - python 大数据分析
    【编程题】【Scratch二级】2022.03 跳跃游戏
    短视频怎么做才能赚钱?短视频创作应该注意什么问题?
    Cookie
    【数据库内核分析系列】:数据库表的创建过程
  • 原文地址:https://blog.csdn.net/qq_62462797/article/details/126794273