awk 文本编辑器
1、简介
- 文本编辑器 非交互式的编辑器 编程语言
- 功能:对文本数据进行汇总和处理 是一个报告生成器 能够对数据进行排版
- 工作模式:行工作模式 读入一行 将整行内容存在$0里,一行等于一个记录 记录分隔符默认换行符,使用内置变量FS(字段分隔符)分割一行 存到$1-$100 字段 列,$NF=最后一列
- 与sed不同点:sed主要处理行 awk主要处理列,sed处理动作必须与文件内容相关 awk处理动作可以与文件内容无关 动作要用{}
语法:awk 选项 ''模式{动作}'' 文件列表
awk 'BEGIN{sum=0}{sum++}END{print sum}' passwd 统计行
BEGIN模式--处理前 标准模式 END模式--处理完(三种模式可以独立存在)
2、分隔符
-F 指定分隔符
- 默认使用空白
- 单个字符
- 复合分隔符 多个字符组成的分隔符 ":/"
- 多个分割符 同时指定多个分隔符 " +|%"
- 每个字符为一字段 以空为分隔符 ""
3、表达式
- 符串加“”
- x ~ /y/ 匹配正则
- x !~ /y/ 不匹配正则 == != ~ !
- 数值比较不需要加“” > < >= <= == !=
- 算术运算 -x 负数 +x(x) 正数 x+y x-y x*y x/y x%y x**y x^y (x的y次幂)
- 逻辑运算符 && || ! 例:awk -F: '$3>=59&&$3<99{print}' /etc/passwd uid为59-99
4、print
- 输出 print 各个输出字段之间用逗号分隔 而输出时默认以空白分隔
- 后面如果不指定字段 那么就会打印一整行
- 输出时默认是有换行符的
- printf 格式化输出 默认没有换行
5、内置变量
- $0 表示整行的内容
- $1~$100 第几列
- NF 当前行的字段数 $NF--最后一段 $(NF-1)--倒数第二段
- NR 处理的记录数(一般可以看成行号) 绝对记录数
- FNR 当前文件所处理的记录数 相对记录数--行号
- FS 字段分隔符 默认空白
- RS 记录分隔符 即行的分隔符
- awk 'BEGIN{FS=":"}/sh$/{print $1,$3}' /etc/passwd 指定字段分隔符
- awk 'BEGIN{RS=":"}{print NR,$0}' passwd NR 显示记录个数 指定记录分隔符
6、自定义变量
- 命名 字母 数字 下划线组成 不能以数字开头
- 赋值 变量名=数值
- 变量名=“字符串” 此处一定有引号
- 取消变量 delete name
- 变量的长度 length(name)
7、算术运算
- a+=b 相当于 a=a+b
- b=a++ 相当于 b=a a=a+1 a++ 先赋值 再自增
- b=++a 相当于 a=a+1 b=a ++b 先自增 再赋值
- 在BEGIN模式可以直接计算 awk 'BEGIN{print 2+2}'
- 在标准模式进行运算 echo |awk '{print 2+2}'
例:awk 'BEGIN{a=10;b=a++;print a,b}' 得:a=11 b=10
8、示例
命令 | 说明 |
---|---|
awk -F: '$1=="root"{print}' /etc/passwd | 用户为root,以":"为分割符 |
awk -F: '$1~/root/{print}' /etc/passwd | 用户名包含root |
awk -F: '$0~/root/{print}' /etc/passwd | 包含root的行 |
awk -F: '$3%2==1{print}' /etc/passwd | uid为奇数 |
awk -F: '{print $1"\t"$3"\t"$4}' /etc/passwd | 结果以制表符分隔(字符加“”) |
awk -F: '{print $2,$1}' /etc/passwd | 交换$1 $2 |
seq 100|awk '$0%7==0 ||$0~/7/' | 打印100以内能被7整除或者包含7的数 |
awk '{print $0"\n"}' passwd | 每行下打印空行 |
ifconfig |awk '/broadcast/{print $2}' | 打印出IP地址 |
ifconfig ens33|awk 'FNR==2{print $2}' | NR=2 第二行 |
df -Th|awk -F " +|%" '/\/$/{print $6}' | 打印出根分区已用量 |
awk -F: '{print $NF}' passwd | $NF 最后一列 |
awk '{print FNR,$0}' passwd | 给文件编号 |
awk -F: '$1~/^.{3}$/{print $1":"$3}' /etc/passwd | 打印用户名为三个字符 |
awk 'BEGIN{a=0}{/sh$/ && a++}END{print a}' /etc/passwd | 统计可登陆用户数量 |
awk -f test.awk /etc/passwd |
执行awk脚本 |
9、判断循环
- 语法:awk 'if(条件表达式){动作}else{动作}' file
- 多分支判断:awk ''{if(条件表达式){动作}else if(条件表达式){动作}else{动作}} file
- while循环:while(条件){动作;变量更新}
- for循环:for(变量初值;判断条件;变量的更新)
- 循环控制语句:continue break exit next--跳过本行
10、数组
awk数组为关联数组 即可以使用字符串作下标
awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' passwd |sort -nr|head -5
11、示例
命令 | 说明 |
---|---|
awk '{if(/adm/){print $0"\n"}else{print $0}}' passwd | 在含adm行下打印空行 |
awk '{a=0;for(i=1;i<=$NF;i++){if(a<$i)(a=$i)}{print a}}' wenjain | 每行取最大值 |
awk 'BEGIN{n=1;max=0}{for(n=1;n<=NF;n++){i[$n]=$n;if(i[$n]>=max)max=i[$n]}{print max}{max=0}}' wenjain | |
awk 'BEGIN{max = 0}{if($1 > max) max = $1}END{print max}' a.txt | 每列最大值 |
awk '{sum += $1}END{print sum/NR}' a.txt | 每列平均值 |
awk 'BEGIN{RS=":"}FNR<=7{print }' passwd | 第一行字段纵向打印 |
awk -F: 'NR==1{for(i=1;i<=NF;i++){print $i}}' passwd | |
awk 'BEGIN{for(i=1;i<10;i++) {for(j=1;j<=i;j++) {printf "%d%s%d%s%d\t",j,"",i,"=",ij;}printf "\n"}}' | 九九乘法表 |
awk 'BEGIN{for(n=0;n++<9;){for(i=0;i++<n;)printf i"x"n"="i*n " \t";print" "}}' | |
awk 'BEGIN{FS=":"}{for(i=NF;i>=1;i--){if(i!=1){printf $i":"}else{printf $i}}printf "\n"}' passwd | 倒序输出文件的每一列 |
awk 'NR==FNR{a[$1]}NR!=FNR{if(!($1 in a))print $0}' b.txt a.txt | 打印a文件中有而b文件中没有的内容 |
awk '{if(NR==FNR){a[$1]=1}else{if(a[$1]!=1){print $1}}}' b.txt a.txt | |
awk '{if(NR==FNR){a[$1]=1}else{delete a[$1]}}END{for(i in a){print i}}' a.txt b.txt |