Linux文本三剑客之一——awk详解(1)——awk看这两篇
shell编程三剑客
- grep --> egrep --> 文本过滤 查询
- ak 文本截取
- sed 文本的替换和修改
目录
ak
ak也可以做小数运算
ak命令简要处理流程
ak的数据字段变量
ak命令的基本语法
ak基本命令示例
ak用 -F 来指定分隔符separater、delimiter
ak命令的完整语法
ak命令的执行过程
ak命令的操作符
ak命令的引用shell变量
ak里的变量的传递问题和shell脚本的传参问题
练习
经典面试题
ak
- ak 是一门模式扫描和处理的语言 --> 专门进行文本截取和分析的工具
- 支持流控、正则
- gak - pattern scanning and processing language
ak也可以做小数运算
ak命令简要处理流程
ak的数据字段变量
- $0 表示整行文本
- $1 表示文本中第一个数据字段
- $2 表示文本中第二个数据字段
- $n 表示文本中第n个数据字段
ak命令的基本语法
- ak的指令一定要用单引号引起,动作一定要用花括号括起
- 模式可以是正则表达式、条件表达式或两种组合
- 如果模式是正则表达式要用/定界符
- 多个动作之间用;分开
- 引用自定义变量,不需要接$符号
ak基本命令示例
ak命令简要处理流程
ak的数据字段变量
- $0 表示整行文本
- $1 表示文本中第一个数据字段
- $2 表示文本中第二个数据字段
- $n 表示文本中第n个数据字段
ak命令的基本语法
- ak的指令一定要用单引号引起,动作一定要用花括号括起
- 模式可以是正则表达式、条件表达式或两种组合
- 如果模式是正则表达式要用/定界符
- 多个动作之间用;分开
- 引用自定义变量,不需要接$符号
ak基本命令示例
- $0 表示整行文本
- $1 表示文本中第一个数据字段
- $2 表示文本中第二个数据字段
- $n 表示文本中第n个数据字段
ak命令的基本语法
- ak的指令一定要用单引号引起,动作一定要用花括号括起
- 模式可以是正则表达式、条件表达式或两种组合
- 如果模式是正则表达式要用/定界符
- 多个动作之间用;分开
- 引用自定义变量,不需要接$符号
ak基本命令示例
- 如果模式是正则表达式要用/定界符
# 只有模式没有动作,结果和grep一样,显示$0 ak '/bash/' /etc/passd # 只有动作没有模式,就直接执行动作 ho | ak '{print $2}' # 以冒号为分隔符,显示以h开头的行的第一列和第七列 ak -F: '/^h/{print $1,$7}' /etc/passd # 不显示以a或b或c开头的行的第一列和第七列 # [^ ] 中括号里面的^表示取反,'^[^ ]'中括号外面的^表示以中括号里面的内容开头 ak -F: '/^[^abc]/{print $1,$7}' /etc/passd # 以 : 或者 / 作为分隔符显示第1列和第10列 ak -F '[:/]' '{print $1,$10}' /etc/passd
ak用 -F 来指定分隔符separater、delimiter
- 默认的字段分隔符是任意空白字符(空格或者TAB)
- 输入分隔符 FS = filed separater
- 输出分隔符 OFS = output filed separate
- [root@kafka01 yum.repos.d]# ak -F: '{print $1,$3,$5}' /etc/passd
- 输入分隔符是冒号 输出分隔符默认为空格
- [root@kafka01 yum.repos.d]# ak -F: 'OFS="#"{print $1,$3,$5}' /etc/passd
- 指定输出符为 # 号
- , 逗号其实就是在调用输出分隔符
- [root@kafka01 ~]# ak -F: 'OFS=","{print $1,$3,$5}' /etc/passd > passd.csv
- 方便重定向为csv文件
- [root@kafka01 yum.repos.d]# ak -F: '{print $1" "$3"#"$5}' /etc/passd
- 自己加分隔符
ak命令的完整语法
- 输入分隔符是冒号 输出分隔符默认为空格
- 指定输出符为 # 号
- , 逗号其实就是在调用输出分隔符
- 方便重定向为csv文件
- 自己加分隔符
ak命令的执行过程
- 先执行BEGIN{mands}语句块中的语句
- 从文件或 stdin 中读取第1行,
- 查看有无模式匹配(/bash/ 找有bash的行), 若无则匹配下一行,如果每行都不匹配就执行END{}中的语句
- 若有则检查该整行与pattern是否匹配, 若匹配, 则执行{}中的语句,若不匹配则不执行{}中的语句,接着读取下一行
- 重复这个过程, 直到所有行被读取完毕
- 执行END{mands}语句块中的语句
- 文字太繁琐!举例就懂啦!
[root@kafka01 1-6]# ak -F: 'BEGIN{print "~~~start~~~"} /bash/{print $1,$3} END{print "~~~end~~~"}' /etc/passd
~~~start~~~
root 0
~~~end~~~
[root@kafka01 1-6]# ak -F: 'BEGIN{print "~~~start~~~"} /bash$/{print $1,$3} END{print "~~~end~~~"}' /etc/passd
~~~start~~~
root 0
~~~end~~~
[root@kafka01 1-6]# ak -F: 'BEGIN{print "~~~start~~~"} /^zabbix/{print $1,$3} END{print "~~~end~~~"}' /etc/passd
~~~start~~~
zabbix 992
~~~end~~~
pattern部分每行都执行(可以使用正则),BEGIN、END部分只执行一次
[root@kafka01 1-6]# ak 'BEGIN{i=0}{i++}END{print i}' /etc/passd # 统计文件行数 [root@kafka01 1-6]# ak -F: '{print $1,NR}' /etc/passd NR可以直接显示行号
- NRnumber of record 显示行号 (常用!很方便!很重要!)
- NFnumber of filed 统计一行里字段数
# 显示用户名,行号和一个字段 [root@kafka01 1-6]# ak -F: '{print $1,NR,$NF}' /etc/passd # 显示用户名,行号和倒数第二个字段 [root@kafka01 1-6]# ak -F: '{print $1,NR,$(NF-1)}' /etc/passd # 显示3到5行 [root@kafka01 1-6]# ak 'NR==3,NR==5{print NR,$0}' /etc/passd 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin # 显示行号大于2的 (只显示df -h结果的第一列文件系统) [root@kafka01 1-6]# df -Th|ak 'NR>=2 {print $1}'
- $NF 取一个字段
ak命令的操作符
数学运算+,-,,/, %,++,- -
逻辑关系符&&, ||, !
- && 比 || 的优先级要高
比较操作符>,<,>=,!=,<=,==,~,!~
文本数据表达式== (精确匹配)
~ 波浪号表示匹配后面的模式(模糊匹配)
如
[root@kafka01 1-6]# ho | ak '$2 ~ /pts/{print $1}' [root@kafka01 1-6]# ak -F: '$3 ~ /<...>/ {print $1,$3}' /etc/passd
- < 单词的界定符 单词以什么什么开头
- > 表示单词以什么什么结尾
- . 点表示单个任意字符
[root@kafka01 1-6]# ak -F: '$3 ~ /[0-9]{3}/ {print $1,$3}' /etc/passd
[root@kafka01 1-6]# ak -F: '$3 ~ /<[0-9]{3}>/ {print $1,$3}' /etc/passd
[root@kafka01 1-6]# cat mobile_phone.txt | grep " VIVO OPPO 12345 feng@qq. [root@kafka01 1-6]# cat mobile_phone.txt | grep "mi>" xiaomi huaei XIAOMI HUAWEI xiaomi dami 正则还支持 bubingb 界定单词,只是查找ubing单词,包含ubing的不算 bubing 单词以ubing开头 ubingb 单词以ubing结尾 定界单词,只是查找ubing单词,包含ubing的不算 -v 引入shell变量 -v 常用在写脚本中,比如我们把某个东西得到了,要通过它来截取一段文字或其他操作 不使用-v选项,直接使用shell里的变量,需要使用双引号,{}括号里的$符号需要转义,举例如下 也可以使用单引号,将变量引起来,然后前面加一个$符号引用变量的值,相当于取2次值 一下 可以在BEGIN部分定义,整个处理的过程都可以使用,END部分也可以使用 往脚本里传递参数 shell里的变量传递到ak里的问题? 1. 统计名字里包含a字母用户的数量,输出用户名 2. 统计/etc/passd文件里的使用bash的用户的个数,并且还要显示出来这些行 3. 取出ip地址 4.使用ifconfig,使用ak显示eth0的入站流量和出站流量(字节) 统计每秒钟ens33网卡的接受和发送数据的流量(编写脚本或使用atch命令) 5.使用ak命令统计以r开头的用户数目,显示如下效果 6. 判断系统里哪些用户没有设置密码或者密码为空的用户,输出这些用户的名字,并且统计没有设置密码的用户个数。 提示 1.如果有一列数字,怎么加起来 2.检查/var/log/secure日志文件,如果有主机用root用户连接服务器的ssh服务失败次数超过10次(10次必须使用变量),就将这个IP地址加入/etc/hosts.deny文件(或者使用iptables)拒绝其访问,如果这个IP已经存在(已经存在在iptables链里了)就无需重复添加到/etc/hosts.deny文件 需求分析 下一篇还会继续探讨ak中支持的函数和结构化语句!我们下篇见!babcb等于
举例(学了以上知识,要看懂以下语句喔)
[root@kafka01 1-6]# seq 100 | ak '$1 % 5 == 0 || $1 ~ /^1/ {print $1}'
[root@kafka01 1-6]# ak -F: ' $1 == "root" {print $1,$3}' /etc/passd
[root@kafka01 1-6]# ps aux | ak '$2 <=10 {print $11}' PID号小于10的命令
ak命令的引用shell变量
[root@kafka01 1-6]# name="lmy"
[root@kafka01 1-6]# echo | ak -v ne_name=$name '{print ne_name}'
lmy
[root@kafka01 1-6]# cat user.sh
read -p "please input your name:" u_name
echo |ak -v ne_name=$u_name -F: '$1 == ne_name {print $1,$3}' /etc/passd
[root@kafka01 1-6]# bash user.sh
please input your name:zabbix
zabbix 992
[root@kafka01 1-6]# abc=pcp
[root@kafka01 1-6]# ak -F: "/^$abc/{print NR,$0}" /etc/passd
28 pcp:x:993:988:Performance Co-Pilot:/var/lib/pcp:/sbin/nologin
[root@kafka01 1-6]# name=zabbix
[root@kafka01 1-6]# ak -F: "$1~ /$name/ {print $1,$3}" /etc/passd
zabbix 992
[root@kafka01 1-6]# sg=3
[root@kafka01 1-6]# ak -F: '/root/{print $1,$'$sg'}' /etc/passd
root 0
operator 11
ak里的变量的传递问题和shell脚本的传参问题
cat /etc/passd|ak 'BEGIN{OFS="####";FS=":"}{print $1,$3}'
练习
ak -F: 'BEGIN{i=0} $1 ~/a/ {i++;print $1,i}END{print i}' /etc/passd
ak -F: 'BEGIN{i=0}{if ($1 ~/a/)print$1,i++}END{print i}' /etc/passd
ak -F: 'BEGIN{i=0} $NF ~ /bash/{i++;print $1,i}END{print i}' /etc/passd
[root@kafka01 ~]# ip add| ak '/i.ens33/{print $2}'
[root@kafka01 ~]# ip add| ak '$NF ~ /ens33/{print $2}'
[root@kafka01 ~]# ifconfig ens33|ak 'NR==5||NR==7{print $5}'
[root@kafka01 ~]# ifconfig ens33|ak '$0 ~ /RX.bytes|TX .bytes/{print $5}'
atch -n 1 -d "ifconfig ens33|ak 'NR==5||NR==7{print $5}'"
[root@kafka01 ~]# cat /etc/passd|ak -F: 'BEGIN{i=0}$1 ~ /^r/{print $1;i++}END{print i}'
[root@kafka01 1-6ak]# ak -F: 'BENGIN{i=0}length($2)<=2{print $1,"user not set passord";i++}END{print i}' /etc/shado
经典面试题
[root@kafka01 1-6]# cat number.txt
1
2
3
4
5
[root@kafka01 1-6]# cat number.txt |ak 'BEGIN{i=0}{i+=$0}END{print i}'
15
[root@kafka01 1-6ak]# cat ssh_secure.sh
#!/bin/bash
# 检查/var/log/secure日志文件,如果有主机用root用户连接服务器的ssh服务失败次数超过3次(3次必须使用变量),就将这个IP使用iptables拒绝其访问,如果这个IP已经存在iptables链里了,就无需重复添加
# 得到登录失败次数大于3的主机ip地址
failed_host=$(cat /var/log/secure |ak '$0 ~ /Failed/{print $(NF-3)}'|sort|uniq -c|ak '$1>2{print $2}')
# 得到iptables中的ssh服务拦截主机ip
exist_host=$(iptables -L INPUT -n |egrep '22>' |ak '{print $4}')
# 将不在ssh拦截的主机添加进iptables
for i in $failed_host
do
if ! echo $exist_host|egrep $i
then
iptables -A INPUT -s $i -p tcp --dport 22 -j DROP
fi
done
1.这个脚本需要一直执行
2.查看/var/log/secure文件,统计出Failed passord行的ip地址,一旦这个ip地址连接的次数超过10,就将这个ip地址加入黑名单/etc/hosts.deny
3.sshd:172.16.145.128 追加到/etc/hosts.deny文件里#!/bin/bash
ak '$0~/Failed/{print $11}' /var/log/secure|sort|uniq -c|ak '{print $1,$2}' >sshd.txt
ip_addr=($(ak '{print $2}' sshd.txt))
ip_num=($(ak '{print $1}' sshd.txt))
for i in ${!ip_addr[@]}
do
if egrep "${ip_addr[i]}" /etc/hosts.deny &>/dev/null
then
echo "${ip_addr[i]} aready exists"
echo "${ip_addr[i]}" have aess ${ip_num[i]} times
else
echo "################################"
((${ip_num[i]} >10 ))&&echo "sshd:${ip_addr[i]}" >>/etc/hosts.deny
echo "${ip_addr[i]}" have aess ${ip_num[i]} times
fi
done
hile true
do
IP_list=($(cat /var/log/secure|ak '{print $6,$11}'|egrep '^Failed'|sort|uniq -c|ak '{if($1>10) print $3}'))
for i in ${!IP_list[@]}
do
if cat /etc/hosts.deny|egrep "${IP_list[i]}" &>/dev/null
then
:
else
sed -i "$ a sshd:${IP_list[i]}:deny" /etc/hosts.deny
fi
done
sleep 5
done
空调维修
- 海信电视维修站 海信电视维修站点
- 格兰仕空调售后电话 格兰仕空调维修售后服务电
- 家电售后服务 家电售后服务流程
- 华扬太阳能维修 华扬太阳能维修收费标准表
- 三菱电机空调维修 三菱电机空调维修费用高吗
- 美的燃气灶维修 美的燃气灶维修收费标准明细
- 科龙空调售后服务 科龙空调售后服务网点
- 华帝热水器维修 华帝热水器维修常见故障
- 康泉热水器维修 康泉热水器维修故障
- 华凌冰箱维修电话 华凌冰箱维修点电话
- 海尔维修站 海尔维修站点地址在哪里
- 北京海信空调维修 北京海信空调售后服务
- 科龙空调维修 科龙空调维修故障
- 皇明太阳能售后 皇明太阳能售后维修点
- 海信冰箱售后服务 海信冰箱售后服务热线电话
- 海尔热水器服务热线