AWK
目标 : AWK 命令行模式
相关内部变量
打印函数print 常用
awk正则 匹配
- awk 编程语言 ,文本 与 数据 处理,逐行扫描,匹配行操作
gawk gun 开源
- 使用方法
(a)命令模式 awk 选项 ‘commands’ 文件名
-F分隔符,默认空格 cut -d:
-v 变量并赋值
正则表达式,地址定位 ‘NR==1,NR==5{awk语句}’
‘/^root/,/^ftp/{awk语句}’
‘{awk语句1;awk语句2}’ ‘{print $0; print $1}’
BEGIN...END... 处理一件事情 前后 做些什么
‘BEGIN{awk语句};{处理中};END{awk语句}’
‘BEGIN{awk语句};{处理中}’
{处理中};END{awk语句}’
引用shell变量 ,需用双引号引起
(b) 脚本模式
执行
1)awk 选项 -f awk脚本 无法修改源文件
awk -f awk。sh filename
- 。/awk脚本(绝对路径) 处理文件
。/awk。sh filename
编写
#!/bin/awk -f
无需引号 保护命令 , 多个命令 ;分号间隔
- awk内部相关变量
$0 当前处理行的所有记录 awk ,逐行扫描处理
$1...$n 以间隔符切割的字段 awk -F:‘{print $1,$3}’ 空格
NF 列数,分隔符分割 $NF最后一列 $(NF-1)
FNR/NR 行号
awk -F' ' ' {print $1,$(NF-1),$NF, NF}' aaa.txt
匹配字符 所在行的第一个
awk '/end/{print $1}' aaa.txt
awk 'NR==1,NR==5;/^root/{print $0 }' aaa.txt 1-5行
两个定位 ,中间 要加上 ; 分隔符,否则报错 。但会显示错误
print “” 双引号内 ,可以加 \t 制表符 ,汉字
{print $1“显示的内容是\t\t”}
输入 就是 读入的。 输出 就是 读出的。
FS 不用-F,在{}中定义 ‘BEGIN{FS=”:”}{print $1 ,$3}’
Shell注意 单双引号。。。。切换使用
awk 'BEGIN{FS=" "};/^hei/,/^hi/{print $1,$NF}' aaa.txt
awk 'BEGIN{FS=".";ORS='\t\t'};/f/{print $0}' 1.t
OFS 输出字段间隔符,默认换行 ‘BEGIN{OFS=”\t”};{print $1 ,$3}’
RS 输入记录分割符,默认换行也存在 ‘BEGIN{RS=”\t”};{print $0}’
ORS 输出 ‘BEGIN{ORS=”\n\n”};{print $1,$3}’
FILENAME 当前输入的文件名
- awk工作原理
逐行扫描 放至 是$0 中 ,以换行符 RS 结束 。 如何确认一行结束
每行 被间隔符 FS 分成自诉案 默认空格/制表符
print时 ,OFS分割 默认空格
处理完后 ,新的一行 放入 $0 中
- awk变量定义
awk -v num=3 ‘BEGIN{print num }’ 不要加 $ 符号
awk 'BEGIN{ORS="@";ORS="@"}{print $0}' aaa.txt
(6)BEGIN....END使用
‘BEGIN{处理前};{处理中;多条指令};END{处理后}’
- awk -F:
'BEGIN{ FS=”:”; print "123\t\t321\n****"};
{print $1"\t\t"$(NF-1)};
END{print "*************"}'
aaa.txt
awk
'BEGIN{FS=":";print "uname\t\th_dir\t\tshell"};
{print $1"\t\t"$6"\t\t"$NF};
{printf "%-15s %-25s %-20s\n", $1,$6,$NF}; 格式化输出
END{print "*******************"}'
/etc/passwd
- 格式化输出
print函数 类似echo
printf 函数
f "%-15s %-25s %-20s\n", $1,$6,$NF};
%s 字符类型 %d 数值类型
- 左对齐 默认右对齐
printf默认不会行尾自动换行 ,加\n 类似 echo -n
(7)awk 正则
~ 匹配 !~ 不匹配 && || > < >= <= 等等
练习:
以 bash$ 结尾
- 第一行到,lp开头的行 两个 ==
打印的是 $0
awk -F: 'NR==1,/^lp/{print $0}' /etc/passwd
或者 ||
'/^root/||/^lp/{print $0}'
grep -E ^root | ^lp 且 | 两端 不要有空格
sed -n '/^root/p;/^lp/p'
5 - 10行
'NR==5,NR==10{print $0}'
'NR>=5&&NR<=10;/bash$/ {print $0}'
;后还可 ,在添加命令 ; 相当于 &&
默认 以 空格 -F ,定义 多个分隔符 -F “【: 】+”
ifconfig eth0 | awk -F: 'NR==2{print $2,$3,$4}' | awk '{print$1,$3,$5}'
让不换行的 ,换行
ifconfig eth0|awk 'NR==2' | awk -F "[: ]+" 'BEGIN{OFS=’\n’};{print $4,$6,$8}'
冒号 空格 +(一个或多个) ”“括起来
NR==1,NR==3 && /bash$/ 是不对的
NR==1 && NR==3 && /bash$/ 正确
awk脚本编程
- 流程控制语句
awk 选项 ‘正则,地址定位{ awk语句}’
无需 ;
{ if(表达式) {语句;语句;。。。} else if (){ } else {} }
对比if 【】; then ***;elif ***;else**; fi
awk 'BEGIN{if ($(id -u)==0){print "admin"}}'
(1)都是在 BEGIN,所以不用 ;
(2)注意 print 使用双 “
(3) 使用shell指令 $( 指令) 符号
awk -F: '{if ($3<=500){print "admin"} else {print "普 通用户"} }' passwd
统计passwd 用户
i ,j ,k 可以直接使用
awk -F: '{ if($3==0){i++} else if($3<=500 && $3>0){j++} else{k++}} END{ print "root"i",系统"j",普通" k}' passwd
- 循环语句
while awk ‘BEGIN { i=1;while(i<=10){sum+=i ; i++};print sum }’
for awk ‘BEGIN { for(i=1;i<=10; i++ ){ sum+=i};print sum }’
for((i=1;i<=10;i+=2)); do echo $i; done | awk -v sum=0 '{sum+=$0};END{print sum}' 要赋值 加$ 0 或 $ i
awk 'BEGIN{ for(i=1;i<=5;i++){ for(j=1;j<=i;j++){printf j}; print } }'
printf 不换行
- 算数运算 小数
+ - * / % ^幂
awk 'BEGIN{print 2^3}' 没有BEGIN 的 话,后面要跟文件名