awk 独立的编程语言 (变量 内置变量 流程控制 函数 数组)
在写脚本时使用awk获取数据给程序处理
awk独立使用时,主要用来对数据做统计
命令格式
awk [选项] '处理动作' 文件列表 (多个文件之间用空格间隔)
命令 | awk [选项] '处理动作'
awk处理数据方式:
以行为处理单位;对数据进行逐行处理
处理完当前行 把当前行的处理结果输出后自动对一行进行处理
直到处理完文件中所有行为止
默认是逐行读入数据,逐行处理数据。要想让awk只处理指定的行。加条件
只有当前行与条件匹配才执行处理动作,反之则不处理
awk [选项] '条件{处理动作}' 文件列表
条件的表示方式:
1/正则表达式/
2数值比较
3字符比较
4逻辑比较
选项
-F 指定分割域时的分割符号。默认分割符号是空格和tab健
awk 内置变量
$0 保存awk当前读放行的内容
FILENAME 保存awk当前处理文件的文件名
NR 保存awk当前处理的行数
FNR 保存awk当前处理的行在文件中的行数
NF 存放用指定分割符号分割后,当前行,列(域)的个数
$1...$n 表示是用指定的分割符 分割数据后的域
$1 变量第1列 $2 第2列
FS 保存字段分割符号 默认值空格和tab健 (FS=
ENVIRON["系统环境"] (数组类型)调用系统环境变量的值
echo $USER $HOSTNAME
awk '{print ENVIRON["HOSTNAME"]},ENVIRON["USER"]}' a.txt
ENVIRON[“系统环境变量”] 让awk调用系统环境变量
-v 让awk使用shell自定义变量
#name=jim
#awk -v mz=$name '{print mz}' a.txt
把awk当前系统已有的用户名输出屏幕上 /etc/passwd
awk -F":" '{print NR,$1,$6}' /etc/passwd | head -3
用户名 家目录
root/root
bin/bin
daemon /sbin
共处理 3 行
awk 'BEGIN{FS=":";print "行号\t用户名\t家目录"}{print NR"\t",$1"\t",$6}END{print "共处理了"NR"行"}' /etc/passwd
awk处理数据顺序
BEGIN{ }行前处理: 没读入行之前执行的动作
初始化操作都写在BEGIN{}里
{ } 行处理: 读入行时执行的动作
对读放的行做处理
END{ } 行后处理: 行读完之后执行的动作
做总结性输出操作写在END{}里
每一个处理都可以单独使用,也可以重复使用,也可以一起使用
head -8 /etc/passwd | awk 'BEGIN{print NR}{PRINT NR}END{print NR}'
条件的表示方式:
1、/正则表达式/
awk ‘/正则表达式/{处理动作}' 文件名
awk '/root/{print NR,$0}'/etc/passwd
awk '/[0-9]/{print $0}' /etc/passwd
~不匹配
!~不匹配
awk -F":" '$1~/a/{print $1,$3}' /etc/passwd
awk -F":" '$1!~/a/{print $1,$3}' /etc/passwd
2、数值比较 == != > >= < <=
awk -F":" '$3==0{print $1,$3}' /etc/passwd
awk -F":" '$3<10{print $1,$3}' /etc/passwd
3、字符比较 == !=
awk -F":" '$1!="bin"{print $0}' /etc/passwd
awk -F":" '$1=="root"{print $0}' /etc/passwd
4、逻辑比较(有多个判断条件时使用)
&& 逻辑与
|| 逻辑或
! 逻辑非
awk -F":" '$3>=5 && $3<=10{print $1,$3}' /etc/passwd
awk -F":" '$3==5 || $3==7{print $1,$3}' /etc/passwd
awk运算符号(与shell里的运算符方式相同)
+ - * / %
+= -= *= /=
++ --
awk里变量的定义与调用
变量名=值
调用 变量名
* 也可以不定义直接调用
awk -F":" 'NR<=3{i=$1;print i}' /etc/passwd
统计内建用户和外建用户的个数
awk -F":" 'BEGIN{i=0;j=0}$3>=500{i++}$3<=499{j++}END{print
"inside user "i" 个";print "outside user "j" 个"}' /etc/passwd
awk 流程控制(流程控制的执行过程和shell里流程控制执行过程一样,只是语法格式变了)
一、分支结构
单分支
if(条件表达式)执行的操作1
if(条件表达式){条件成立时执行的操作1;执行操作2;执行操作N}
双分支
if(条件表达式){
动作1;动作2;动作N
}
else{
动作1;动作2;动作N
}
awk -F":" '{ if($3<=499){i++}else{j++}}END{print i;print j}' /etc/passwd
多分支
if(条件表达式){
动作1;动作2;动作N
}
else if(条件表达式){
动作1;动作2;动作N
}
......
esle{
动作1;动作2;动作N
}
awk -F":" 'BEGIN{x=0;y=0;z=0}{if($3<100){x++}else if
($3>=100&&$3<=499){y++}else if($3>=500){z++}else{print "no user"}}
END{print x,y,z}' /etc/passwd
调用awk脚本对文件处理
awk -f xxx.awk /etc/passwd
vim xxx.awk
#!/usr/bin/awk -f
BEGIN{
FS=":"
x=0
y=0
z=0
}
{
if($3<=499){
x++
}else{
y++
}
}
END{
print "内建用户个数是 "x" 个"
print "外建用户个数是 "y" 个"
}
#chmod +x xxx.awk /etc/passwd
./xxx.awk
二、循环结构
for
for(初值;条件表达式:步长){
条件成立时执行的循环体
}
awk "BEGIN{ for(i=1;i<=10;i++){print i}}"
while 先判断条件再执行循环体
while(条件表达式){
条件成立时执行循环体
}
awk -F":" '{while( $3<3 ){print $1,$3;}}' /etc/passwd
awk -F":" '{while( $3<3 ){print $1,$3;$3++}' /etc/passwd
awk -F":" '{while( $3<3 ){print $1,$3;$3=5}}' /etc/passwd
do....while 先执行循环体后判断条件
do{
循环体
}while(条件表达式)
awk 'BEGIN'{i=10:while(i>20){print i;i++}}'
awk 'BEGIN(i=10;do{print i;i--}while(i>20)}'
awk流程控制语句
对awk里的循环结构做执行控制(只要条件成立就执行循环体)
awk数组
break 结束当前所在的循环体
continue 终止本次循环,开始下一次循环
awk 'BEGIN{for(i=1;i<=10;i++){if(i==4)continue;print i}}'
awk 'BEGIN{for(i=1;i<=10;i++){if(i==4)break;print i}'
对awk做控制(逐行读入数据,逐行处理数据)
exit
终止awk读入行
如果有END{}就执行END{}里的动作
如果没有END{}直接结速处理
awk 'NR==4{exit}{print NR,$0}' a.txt
awk 'NR==4{exit}{print NR,$0}END{print NR}' a.txt
next
让awk读取当前行的下一行
awk 'NR==4{next}{print NR,$0}END{print NR}' a.txt
awk数组
定义数组格式:数组名[数字元素下标]=元素值
*数组元素的下标可以使用数字或字符
使用数组元素格式: 数组名[数组元素下标]
输出数组元素的值:print 数组名[数组元素下标]
awk 'BEGIN'{stuname[0]="jim"stuname[1]="tom";print stuname[0];print stuname[1]}'
awk 'BEGIN{ for{i=0;i<=10;i++}{ num[i]=i;print num[i]} }'
awk 'BEGIN{ for(i=0;i<=10;i++){ num[i]=i;print num[2]} }'
awk 'BEGIN{ for(i=0;i<=10;i++){ num[i]=i };print num[2];print num[3] }'
遍历数组循环结构
for(变量名 in 数组名){print 数组名[变量名]}
for( x in num ){ print x;print num[x]}
awk 'BEGIN{for(i=0;i<=10;i++)num[i]="user"i};for(w in num){print w,num[w]}'
把系统前5个用户名存储到数组usergrp里,然后输出数组usergrp的所有元素
head -5 /etc/passwd | awk -F":" '{print $3,$1}'
head -5 /eetc/passwd | awk -F":" '{print usergrp[$3]=$1}END{for(i in usergrp}{print i,usergrp[i]}}'
统计test.txt 文件里每个命令出现的次数
awk '{comm[$1]++}END{for(x in comm){print x,comm[x]}}' test1.txt | sort -rnk 2
awk '{comm[$1]++}END{for(x in comm){print x,comm[x]}}' ~/.bash_history | sort -rnk 2 | head -10
r 按降序排序
n 按数字排序
k 按第2列排序
ps -e 显示系统内的所有进程
-o 指定显示那列的数据
comm 可执行文件名
cmd | 简单命令
pcpu cpu的占用率
pmem 内存使用率
time 累计的cpu时间
etime 进程启动后度过的时间
例子
ps -eo comm,pupu,pmem --sort -pmem | head 按内存使用率降序排序
ps -eo comm,pcpu,pmem --sort +pmem | head 按内存使用率升序排序
ps -e -o comm,pcpu | tail -n +2
自动连接ssh服务器脚本
#!/usr/bin/expect
set login_host 192.168.1.1
set login_user root
set login_password 123456
spawn ssh $login_user@login_host
expect "login_user@login_host's password:"
send "$login_password\r"
expect "#"
send "useradd jim9\r"
expect "#"
send "exit"