awk
显示例子
显示行的所有内容 $0
awk '{print $0}' /etc/passwd
显示hello world (前面的金额echo 控制了 输出1行 与内容无关)
echo asdf |awk '{print "hello world"}'
显示多行hello world (文件内有几行 就显示几行hello world 文件控制了输出的行数)
awk '{print "hello world !"}' /etc/passwd
使用分隔符
awk 'BEGIN{FS=":"}{print "$7"}' /etc/passwd
使用分隔符(功能一样)
awk -F":" '{print $7}' /etc/passwd
使用制表符和字符串
awk -F":" '{print "username: "$1",\t UID:"$3}' /etc/passwd
BEGIN块和END块
通常,对于每个输入行,awk 都会执行每个脚本代码块一次。然而,在许多编程情况中,
可能需要在 awk 开始处理输入文件中的文本之前执行初始化代码。对于这种情况,awk 允许
您定义一个 BEGIN 块。我们在前一个示例中使用了 BEGIN 块。因为 awk 在开始处理输入文
件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它
在程序中以后会引用的全局变量的极佳位置。
awk 还提供了另一个特殊块,叫作 END 块。awk 在处理了输入文件中的所有行之后执行
这个块。通常,END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。
运算符
运算符 && BENGIN_END 例子
算数运算符
free -m|awk 'NR==2{printf "%5.2f%\n",$3*100/$2}'
(a+=5) == (a=a+5)
awk 'BEGIN{a=5}{print a+=5}' #10
逻辑运算符
awk 'BEGIN{a=1;b=2;print (a<b&&a==1)}'
正则运算符
awk 'BEGIN{a="100testaaa";if(a~/100/){print "has 100"}}'
算数运算符
说明,所有用作算术运算符 进行操作,操作数自动转为数值,所有非数值都变为 0
awk 'BEGIN{a="B";printa++,++a}' #0 2
awk 'BEGIN{a="11abc";print a+=1}' #12
三目运算符
awk 'BEGIN{a="B";print a=="B"?"a is B":"a not B"}' #a is B
常用awk 内置变量
变量名 | 属性 |
---|---|
$0 | 当前记录(当前行) |
n | 字段序号(分隔符做出的分隔是一个字段) |
FS | 输入字段的分隔符 一般在BEGIN块里 ,也可以使用 awk -F"" 指定分隔符 |
RS | 输入记录的分隔符 ,默认是回车 |
NF | 当前记录的字段个数 就是有多少列 |
NR | 已经读出的记录数目 也就是行号 从1开始 |
FNR | 针对两个文件,显示两个文件时,将2个文件的行号分开 |
OFS | 输出字段分隔符 默认是 空格 |
ORS | 输出记录的分隔符, 默认是 换行符 |
-v | 引用awk内部变量 例如在''外部指定 OFS |
内置变量例子
查找oldboy运行的程序并结束
ps -ef|awk '$1=="oldboy"{print $2}'|xargs kill -9
指定分隔符FS
awk 'BEGIN{FS=":"}{print $1,$2,$3}' /etc/passwd #指定分隔符为 : ,然后读取列
awk 'BEGIN{FS="[[:space:]+]"}{print $1,$2,$3}' /etc/passwd #分隔符为一个或多个 空格
记录数量NR
ifconfig eth0|awk 'NR==2{print $2}' #IP地址
字段数量NF
awk 'BEGIN{FS=":"}{print NF}' /etc/passwd #查看一个字段有几列 (之前用FS 制定了字段分隔符)
awk -F ":" 'NF==8{print $0}' /etc/passwd #当一个字段有8列的时候输出整行
记录分隔符RS
awk 'BEGIN{RS=":"}{print}' /etc/passwd #把所有:替换成回车
指定字段分隔符OFS
awk 'BEGIN {FS=":";OFS="#"}{print $1,$2,$3}' /etc/passwd
#输出
root#x#0
bin#x#1
daemon#x#2
adm#x#3
lp#x#4
sync#x#5
shutdown#x#6
指定记录分隔符ORS
awk 'BEGIN{ORS="\t"}{print}' /etc/passwd #把默认的回车替换成了制表符
外部引用内部变量
awk -F -vOFS=":" ‘{print $7,$2,$3,$4,$5,$6,$1}’ /etc/passwd
awk正则表达式
正则应用
规则表达式
awk '/REG/{action}' filename #REG是正则表达式 可以将$0中 满足条件的记录送到:action中处理
正则表达式例子
在记录中搜索一个字段
awk '/root/{print }' /etc/passwd #搜索*root* 在记录中
输出第5条记录中包含root的字段
awk -F: '$5~/root/{print }' /etc/passwd
布尔表达式
awk 'bool{action}' filename // bool?action:pass
awk 'BEGIN{FS=":"}$1=="root"{print }' /etc/passwd #如果 第一个字段是 root 则输出
比较表达式
awk '$3>30' /etc/passwd
复合用法
awk -F: '$1=="root"||$4==0{print}' /etc/passwd
if && 循环 && 数组
if
awk -F: '{if{$3==0}{print $1}}' /etc/passwd
awk 提供的非常类似C语言的if语句
使用awk检测每个类型的用户有几个
使用awk 批量删除 用户
创建不同日期的文件
循环
awk的while循环结构 等同于 C语言的 while 循环 . awk 还设有 do while 结构
while 循环
while #想要执行代码就先要满足while条件
do while #无论满不满足 , 第一次的 do 都是可以执行的
continue #跳过此次循环 执行下次循环
break #跳出所有循环 直接结束循环
例子
for 循环
for 循环需要三个参数
for(初始化条件[执行一次];判断条件[执行循环的次数];判断成功后执行的语句[执行循环的次数])
执行顺序: 1,2,3,{},2,3,{},2,3,{},2,3,{}....[直到不满足条件2,跳出循环 执行{}下面的代码]
例子
(一共循环0~99 ,100次循环)
数组array
awk中的数组都是关联数组,数字索引也会转变为字符串索引
{
cities[1] ="beijing"
cities[2] ="shanghai"
cities["three"] ="guangzhou"
for(city in cities){
print city
}
#exit
}
for..in 输出,因为数字是关联属组,默认是无序的,所以通过 下标取得有序属组