awk的语法
awk 参数 处理规则 操作对象
参数
参数-F
参数 -F :指定本文分隔符(默认以空格作为分隔符)
awk -F'/' '{print $NF}' 2.txt :用/作为分隔符,打印最后一列字段
# 案例:打印系统所有用户的解析器:冒号作为分隔符,最后一个字段就是解析器
awk -F: '{print $NF}' /etc/passwd
awk的生命周期
grep、sed、awk都是读一行处理一行,直到处理完成。
1.接收一行作为输入
2.把刚刚读入进来的文本进行分解
3.使用处理规则处理文本
4.输出一行,赋值给$0($0代表当前行),直到处理完成
5.把处理完成之后的所有的数据交给END{}来再次处理
awk当中的预定义变量
$0 :代表当前行
awk '{print $0 "---"}' 2.txt :打印文件内容,每一行就在后面加---
$n : 代表分割后的第n列字段
awk -F/ '{print $1}' 2.txt :打印文件内容:用/分割后的第1列字段
NF :记录每一行用分隔符后的字段数量
awk -F/ '{print NF}' 2.txt :NF打印字段数量
awk -F: '{print $NF}' /etc/passwd :$NF打印最后一列字段
NR :记录行号
awk -F/ '{print NR}' 2.txt
FS :指定文本内容的分隔符(默认空格);自定义变量的优先级要高于-F参数
awk -F/ 'BEGIN{OFS="--"}{print $NF,$1}' 2.txt
awk -F/ 'BEGIN{OFS="--"}{print $1,$2,$3}' 2.txt
awk当中处理规则的执行流程
以下至少有一个,最多有四个。执行流程从上到下。
BEGING : 定义变量
// : 正则,匹配
{} : 处理文本
END{} :打印之前统一处理一遍
awk中的函数
print : 打印(前面举了很多例子了)
printf :格式化打印,给个双引号
awk -F/ 'BEGIN{OFS="|"}{printf"|%-10s|%-10s|\n", $1,$2}' 2.txt
%s : 字符串
%d : 数字
- :左对齐
+ :右对齐
10 :至少占用10个字符
awk中的定位
1.正则表达式 :两个//中间的就是正则表达式
awk -F/ '/^345/{print $0}' 2.txt
# 忽略大小写怎么写?
awk -F/ '/qew|QEW|QEw|QeW|qEW/{print $0}' 2.txt
2.比较表达式 :比较的是本文内的内容;
> : 大于
< : 小于
>= : 大于等于
<= : 小于等于
~ : 匹配正则
!~ : 不匹配正则
# 要求打印属组id大于属主id的所有行
awk -F: '$4 > $3{print $0}' /etc/passwd
# 结尾包含bash的所有行
awk -F: '$NF ~ /bash/{print $0}' /etc/passwd
# 结尾不包含bash的所有行
awk -F: '$NF !~ /bash/{print $0}' /etc/passwd
3.逻辑表达式:
&& : 逻辑与
|| :逻辑或
! :逻辑非
# 属主id加属组id大于2000并且相乘大于2000
awk -F: '$3 + $4 > 2000 && $3 * $4 > 2000{print $0}' /etc/passwd
# 属主id加属组id大于2000或者相乘大于2000
awk -F: '$3 + $4 > 2000 || $3 * $4 > 2000{print $0}' /etc/passwd
# 属主id加属组id不大于2000
awk -F: '!($3 + $4 > 2000){print $0}' /etc/passwd
4.算数表达式:
+ :加
- :减
* :乘
/ :除
% :整除
# 要求属组 + 属主的ID 大于 2000
awk -F: '$3 + $4 > 2000{print $0}' /etc/passwd
#:要求属组 * 属主的ID 大于 2000
awk -F: '$3 * $4 > 2000{print $0}' /etc/passwd
# 要求打印偶数行
awk -F: 'NR % 2 == 0{print $0}' /etc/passwd
# 要求打印奇数行
awk -F: 'NR % 2 == 1{print $0}' /etc/passwd
5.条件表达式:跟比较表达式相似,比较的是自定义的内容;
== :等于
> :大于
< :小于
>= :大于等于
<= :小于等于
# 要求打印第三行
awk -F/ 'NR==1{print $0}' 2.txt
6.范围表达式:
# 打印root开头的行到ftp开头的行
awk -F: '/^root/,/^ftp/{print $0}' /etc/passwd
流程控制
流程控制只存在循环之中。
if
# 如果行的第3列字段大于第4列字段,打印0,否则打印1。
awk -F/ '{if($3>$4){print "0"}else{print "1"}}' 2.txt
# 每隔5行,打印一行横线
awk -F: '{if(NR%5==0){print "----------------"}print $0}' /etc/passwd
格式:
if(){} :单条件
if(){}else{} :双条件
if(){}else if(){}else{} :多条件
for
# 循环打印每行打印2次
awk -F/ '{for(i=2;i>0;i--){print $0}}' 2.txt
格式:
for(i="初始值";条件判断;游标){}
while
# 循环打印每行打印2次,每次后面加打印次数
awk -F/ '{i=1; while(i<=2){print $0, i++}}' 2.txt
格式:
i="初始值"; while(条件判断){}