awk命令学习

一、awk简述

awk :最主要功能:按行取列

awk默认的分隔符:空格和tab键,多个空格会自动压缩。

awk的工作原理:根据指定信息,逐行读取文本内容,然后按照条件进行格式化输出。

二、awk用法

2.1 awk命令

选项:

  • -F :指定分隔符,默认就是空格
  • -v :变量复制

内置变量:

  • $# :#是数字,表示按行需要取出的第几个字段

  • $0 :打印所有,展示整行内容

  • NR :需要处理的行号

  • NF :处理行的字段字数,特殊的,$NF表示当前行的最后一个字段

  • FS :和F一样,都是指定分隔符,比如指定:为分隔符: -F:或者FS=":"

  • OFS :指定输出内容的分隔符

  • RS :行分隔符,可以根据RS的设置把文件内容分割成多个记录,也可以改变行的分隔符,默认是\n,回车,换行。

2.2 命令格式

bash 复制代码
awk -F '操作符 {动作 处理对象}'
  • -F :指定分隔符,如果是空格可以不加
  • 动作:默认就是打印,print

例:

打印行号

bash 复制代码
awk '{print NR}' filename

打印行号和文本内容

bash 复制代码
awk '{print NR,$0}' filename

打印指定行,如第三行

bash 复制代码
awk 'NR==3{print}' filename

打印第三行以后得行

bash 复制代码
awk 'NR>3{print}' filename

打印第三行到第五行

bash 复制代码
awk 'NR==3,NR==5{print}' filename

打印第三行和第五行

bash 复制代码
awk 'NR==3;NR=5{print}' filename

打印偶数行

bash 复制代码
awk 'NR%2==0{print}' filename

打印奇数行

bash 复制代码
awk 'NR%2==1{print}' filename

取出/etc/passwd里的每行第三个字段

bash 复制代码
awk -F: 'print{$3}' /etc/passwd

过滤/etc/passwd里含有root的行,一般很少用awk过滤文本

bash 复制代码
awk -F: '/root/{print}' /etc/passwd

2.3 BEGIN打印模式

bash 复制代码
awk 'BEGIN{预先条件};{处理条件};END{结束条件}'

预先条件 :执行awk命令前的初始化操作

处理条件 :如何对初始值进行操作

结束条件 :处理完之后的操作,一般都是打印

END不是总是需要的,只写BEGIN也可以,比如做一次性操作的计算等

例:有初始条件的操作

bash 复制代码
awk 'BEGIN{x=0};{x++};END{print x}' filename

解释:根据filename文件的行数,对变量x执行++,最后打印出来的就是文件的行数

例:一次性操作

计算10*2

bash 复制代码
awk 'BEGIN{print 10*2}'

计算2的5次方(幂运算)

bash 复制代码
awk 'BEGIN{print 2**5}'
awk 'BEGIN{print 2^5}'

2.4 变量复制

-v :变量复制,把外部变量的值复制到awk命令内部

例:

bash 复制代码
vim test1.sh
a=3
b=4
num=$(awk 'BEGIN{print a+b}')
echo $num

执行test1.sh脚本,发现输出结果为0

bash 复制代码
sh test1.sh
0

这是因为awk命令的内部变量和全局变量隔离,外部的变量没有传进awk命令中去,对test1.sh做如下修改

bash 复制代码
num=$(awk -v a="$a" -v b="$b" 'BEGIN{print a+b}')
bash 复制代码
sh test1.sh
7

如此,才把外部变量传到awk命令内部去

2.5 条件判断

例:

获取/etc/passwd中第三列UID大于999的用户所在的行

bash 复制代码
awk -F: '$3>999 {print $0} ' /etc/passwd

获取/etc/passwd中第三列UID等于1000的用户所在的行

bash 复制代码
awk -F: '$3==1000 {print $0} ' /etc/passwd

注:不能用=,用=会直接赋值,而不是判断

2.6 awk的三元表达式

实际就是一个if...else...语句

bash 复制代码
awk -F: '{num=($3>$4)?$3:$4;{print num;$0}}' /etc/passwd

解释:num=(3\>4)?3:4;

num是定义的变量,将后面判断后得到的结果赋给变量num

($3>$4)? :相当于if [ $3 > $4 ],后面的内容就是为真的时候输出的内容,这里是输出$3

第一个: :相当于else,后面的内容就是判断为假的时候输出的内容,这里是输出$4

后一个; :相当于fi

2.7 awk的精确筛选

bash 复制代码
$n(> < ==)用于比较数值
$n~"字符串" :该字段包含这个字符串
$n!~"字符串" :该字段不包含这个字符串
$n=="字符串" :该字段等于这个字符串
$n!="字符串" :该字段不等于这个字符串
$NF :最后一个字段

例:打印/etc/passwd第七列包含bash这个字段的行,取行的第一列和最后一列

bash 复制代码
awk -F: '$7~"bash" {print $1,$NF}' /etc/passwd

print列的时候不能范围取列,要想打印多个列,必须列出所有要打印的列,用隔开

打印/etc/passwd第七列字段为/bin/bash的行,取行的第一列和最后一列

bash 复制代码
awk -F: '$7=="/bin/bash" {print $1,$NF}' /etc/passwd

解释:使用==时,匹配的内容必须和字段内容完全一致

去除/var/log/messages 文件前5行 第5列的内容

bash 复制代码
head -5 /var/log/messages | awk '{$5=""}1'

解释:awk '{$5=""}1',表示对于每一行,将第5列设为空(即清空第5列),然后打印整行。1 是一个条件,表示打印处理后的结果。

2.8 awk的"且"、"或"条件

且:&&;或:||

例:打印/etc/passwd第一列为root 第七列(最后一列)为/bin/bash的行

bash 复制代码
awk -F: '($1=="root")&&($NF=="/bin/bash") {print $0}' /etc/passwd
# && 两边的条件的()可以不加,但加了更方便阅读

打印/etc/passwd第一列为dhcp 第七列为/bin/bash的行

bash 复制代码
awk -F: '($1=="dhcp")||($NF=="/bin/bash") {print $0}' /etc/passwd

2.9 awk做小数运算

awk做小数运算,有几位小数就算几位小数,也可以指定输出结果的小数位数

例:

bash 复制代码
awk 'BEGIN{printf "%.#f" , 小数运算}'
# {}里的%.#f号表示数字,数字是几就表述输出结果有几位小数,四舍五入
awk 'BEGIN{printf "%.F" , 小数运算}'
# %.F 表示输出结果为整数,四舍五入

2.10 附加内容

curl命令

curl是一个功能强大的命令,可以获取和发送数据

格式:

bash 复制代码
curl 域名
curl IP地址

-O :下载文件到本地

-o :将文件下载到指定路径

-x :发送post请求

-i :可以获取web软件的版本(前提是服务端没有隐藏版本号)

2.11 练习

例1:host.txt文件的内容为

复制代码
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.co

获取其中的所有子域名(www mail ftp 等 )

bash 复制代码
cat host.txt | awk -F'[ .]+' '{print $2}'

解释:-F'[ .]+'表示以空格 .作为分隔符,

例2:使用awk获取 /etc目录下所有文件的总大小

bash 复制代码
ll /etc | awk '/^-/{print sum+=$5} END{print "文件的总大小:"sum/1024"M" }'

解释:ll查看的结果,文件以-开头,文件大小在第5列,把文件大小累加到变量sum,输出sum

例3:监控内存,cpu和硬盘的根目录,超过80%提示用户,写成函数库的行,每天早上 的8:50分,执行一次脚本。

监控各个负载的功能使用函数库的形式实现

函数库文件:testlib.sh

bash 复制代码
# 检测CPU负载
cputest () {
local c=$(top -b -n 1 | awk 'NR==3 {printf "%.F", $2+$4}')
if [[ c -ge 80 ]];then
  echo "当前CPU负载${c}%,超过80%!请及时处理!"
else
  echo "CPU负载正常,当前负载${c}%"
fi
}

# 检测内存负载
memtest () {
local b=$(free -m | awk 'NR==2 {printf "%.F", $3/$2*100 }')
if [[ $b -ge 80 ]];then
  echo "当前内存负载${b}%,超过80%!请及时处理!"
else
  echo "内存负载正常,当前负载${b}%"
fi
}

# 检测根目录负载
blktest () {
local a=$(df -h | awk '$NF=="/" {print $5}' | tr -d "%")
if [[ $a -ge 80 ]];then
  echo "根目录当前使用达到${a}%,超过80%!请及时处理!"
else
  echo "根目录使用空间正常,当前已使用${a}%"
fi
}

每天执行的脚本文件jiankong.sh

bash 复制代码
. /opt/zuoye1/testlib.sh
cputest
memtest
blktest

创建定时任务

bash 复制代码
crontab -e
50 8 * * * /opt/zuoye1/jiankong.sh

查看定时任务

bash 复制代码
crontab -l
50 8 * * * /opt/zuoye1/jiankong.sh
相关推荐
databook9 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar10 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户83562907805110 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_10 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机17 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机18 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机18 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机18 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i18 小时前
drf初步梳理
python·django
每日AI新事件18 小时前
python的异步函数
python