linux awk

awk这个工具的名字是由三个发明者的首字母组合而成,awk和sed一样,也是流式编辑器,将内容一行一行读取到内存中,然后做响应的处理。


工作原理

  1. 先运行行前处理代码(如果有),运行awk命令的时候,还没开始匹配行内容的时候会执行该操作;

  2. 运行行处理代码,将文件内容一行一行的读入内存,按照特定的分隔符将内容切为若干份。切分后的每一份都会赋值给awk内置的变量;

  3. 运行行处理代码,例如print打印等。

  4. 最后运行行后处理代码(如果有),所有行都匹配完了后运行该代码;


使用格式

               awk   [option]   'BEGIN{}模式匹配{所作的操作(主体部分)}END{}' /path
  • BEGIN{} 处理所有行之前所作的操作,会在处理任何输入行之前执行一次

  • END{} 处理完所有行之后所作的操作,在处理所有输入行之后执行一次

  • 模式匹配 就是sed里面的定位(sed和awk一行,不写就表示定位所有行)

  • {xxxx} :这是主体部分,匹配成功后需要执行的操作(对输入的每一行都执行一次)

说明:

  • 默认使用空格将将内容切为若干份,可以使用 -F 参数来手动指定分隔符

  • 使用awk时,一般需要用单引号括起来,防止shell解释其中的任何特殊字符

  • BEGIN 和 END 部分不需要可以省略 awk '匹配模式{操作}' /path/file_name


模式匹配

行定位

单行定位:

通过NR( NR==num)来指定行号,NR是Number of Records(记录的数量)的缩写。

例如: NR==1,表示匹配第一行的内容

多行定位:

通过 && 或 || 连接多个条件

例如: NR>=1 && NR <=10,表示第1行到第10行。 NR1 || NR1表示第1行或第3行。

正则定位

    语法:awk  [option]  '/regex/{所作的操作}'  /path

行号+正则定位

结合正则和行号定位,通过 &&(并且) 或者 ||(或者) 等符号来连接多个条件。

例如: 获取第3行到第7行中间,包含指定内容的行

awk -F: 'NR>=3 && NR<=7 && /nologin/{print $0}' /etc/passwd   

说明:

  • 如果省略模式匹配,和sed一样,表示对所有内容进行匹配

  • 如果省略了相关操作,默认就是采用print的操作方式,print表示输出指定的内容,输出的内容默认以为空格作为分隔符,如果需要更改可以使用OFS指定。

print动作说明

print这个是用来实现打印功能的,和上面所说一样,默认使用空格将一行内容分为若干列(如果需要更改可以使用OFS指定),然后使用内置变量来确定需要输出那一列的内容,输出多列的话就使用逗号进行分隔。

例如: 输出文件中所有行中,第一列内容

awk '{print $1}' /path/file_name

内置变量

除了上面说的NR变量,还有以下常用内置变量

  1. $1 - $n 表示切分后的第几段内容,最后可以有100多段

  2. $0 表示整行内容

  3. NF 表示一共切了几段。NF代表"Number of Fields",即字段的数量

  4. FS 表示行的分隔符,一般使用 -F 选项指定就行了

  5. OFS 用于指定输出分隔符,默认输出分隔符是空格

说明:
awk中,规定只有在引用$0、$1等内置变量的值的时候才会用到"$",引用其他变量时,不管是内置变量,还是自定义变量,都不使用"$",而是直接使用变量名。

awk的常用选项

-F 用于指定每行内容的分隔符,默认是空格

说明:

  • -F 选项后面可以跟随一个基本正则表达式

  • -F 指定分隔符时,如果是单个就不用加引号也行(awk -F:),指定多个分隔符一般添加单引号,如果要使用双引号,需要转义那些在双引号内有特殊含义的字符

例如:

awk -F:  表示使用冒号作为分隔符

awk -F"[ %]" 表示以空格或百分号作为分隔符

awk -F '[,:]'

awk -F ",\\|:" 表示先需要为正则表达式转义,然后再为shell转义

范例:

例如:统计管理员、系统用户和普通用户数量

#!/bin/bash

admin=0
sys=0
normal=0

for uid in `awk -F: '{print $3}' /etc/passwd`
do
    if [ $uid -eq 0 ];then
        let admin++
    elif [ $uid -gt 0 -a $uid -lt 1000 ];then
        let sys++
    else
        let normal++
    fi
done

echo -e "管理员用户数量:" $admin
echo -e "系统用户数量:" $sys
echo -e "普通用户数量:" $normal

例如:获取分区的利用率

df -h | awk '{print $5}'

范例:获取指定网卡的ip地址

ifconfig eth0 | awk 'NR==2{print $2}' #表示取第二行的内容 NR==2就是条件

例如:获取指定网卡的ip地址

ifconfig eth0 | sed -n '2p' | awk '{print $2}'

范例:获取指定网卡的ip地址

ifconfig eth0 | awk 'NR==2{print $2}' #表示取第二行的内容 NR==2就是条件

例如:计算所有名为HGPython3的进程的内存使用量的总和,并输出结果

ps aux | grep HGPython3 | awk '{sum += $6} END{print sum " kb"}'

说明:

awk中的变量不需要定义,直接引用即可,默认情况下,未初始化的变量在awk中的值为0

posted on 2022-07-18 23:40  背对背依靠  阅读(277)  评论(0编辑  收藏  举报