linux awk
awk这个工具的名字是由三个发明者的首字母组合而成,awk和sed一样,也是流式编辑器,将内容一行一行读取到内存中,然后做响应的处理。
工作原理
-
先运行行前处理代码(如果有),运行awk命令的时候,还没开始匹配行内容的时候会执行该操作;
-
运行行处理代码,将文件内容一行一行的读入内存,按照特定的分隔符将内容切为若干份。切分后的每一份都会赋值给awk内置的变量;
-
运行行处理代码,例如print打印等。
-
最后运行行后处理代码(如果有),所有行都匹配完了后运行该代码;
使用格式
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 - $n 表示切分后的第几段内容,最后可以有100多段
-
$0 表示整行内容
-
NF 表示一共切了几段。NF代表"Number of Fields",即字段的数量
-
FS 表示行的分隔符,一般使用 -F 选项指定就行了
-
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