首页 > 代码库 > awk学习随常记录
awk学习随常记录
回顾:字符串处理
数组:
数组 : declare -a
index: 0-
关联数组 : declare -A
编程:数据结构和算法
字符串处理:
切片、查找替换、查找删除、变量赋值
GUN awk:
文本处理三工具: grep ,sed ,awk
grep:grep、egrep 、fgrep:文本过滤工具:pattern
sed:行编辑器
模式空间、保持空间
awk:报告生成器,格式化文本输出;
AWK: aho,weinberger, kernigha 命名就用三个人名字的首字母
awk主要是在unix上使用。linux用的为GUN版的awk简称gawk
基本用法
awk [options] ‘program‘ FILE...
program : PATTERN{ACTION STATEMENT}
语句之间用分号分隔
print,printf
选项:
-F 字段分隔符,指明输入时的字段分隔符
-v 自定义变量 var=value
以文件中的行为单位进行读取,以-F指定的分隔符为标识来分隔读取的内容
整个行为$0 第一片为$1
awk的循环功能不是在行间循环的,awk自身就能遍历文件
tail -3 /etc/fstable|awk ‘{print $2,$4}‘
1、print item1,item2
(1)逗号为分隔符;
(2) 输出的各item可以是字符串,也可以是数值,也可以是awk自己的变量或表达式。
(3) 如省略item,相当于print $0
2、变量
2.1内建变量
FS:input field seperator,默认为空白字符
awk ‘{print $1}‘ /etc/passwd
awk -v FS=":" ‘{print $1}‘ /etc/passwd
等于
awk -F
awk -v FS=‘:‘ ‘{print $1}‘ /etc/passwd
OFS:output field seperator ,默认为空白字符 输出字段默认分隔符
RS:input record seperator,输入时的换行符
OFS:outpu record seperator,输出时的换行符
NF: number of field 每一行的字段数量
NR:number of record 行数:显示一个文件一个有多少行
FNR:file number of record 每一个文件分别计行数
FILENAME:文件名 当前正在正理的文件的文件名
ARGC:命令行中参数的个数
ARGV:保存命令行中所给定的各参数 是一个数组,调用方式为 ARGV[0] ARGV[1]
自定义变量
-v var=value
(1)变量名区分字符大小写
(2)在program中直接定义
3、printf命令
格式化输出:printf FORMAT,item1,item2,item3...
(1)FORMAT是必须给出
(2)printf不行自动换行,需要显式给出换行符,\n
(3)FORMAT中需要分别为后面的每个item指定一个格式化符号:
格式符:
%c:显示字符的ASCII码
%d,%i 显示十进制整数
%e %E 科学计数法数值显示
%g %G 以科学计数或浮点形式显示数值
%u 无符号整数
%% 显示%自身:
%s 显示字符串
awk -F : ‘{printf "Username:%s\n",$1 }‘ /etc/passwd
awk -F : ‘{printf "%s\n",$1 }‘ /etc/passwd
awk -F : ‘{printf "%s",$1 "\n"}‘ /etc/passwd
awk -F : ‘{printf "Username: %s,UDI %d \n",$1,$3}‘ /etc/passwd
修饰符:
#[.#]:第一个数字用来控制显示的宽度,第二个数字用来控制小数点后的精度
%3.1f
awk -F : ‘{printf "Username: %15s,UDI %d \n",$1,$3}‘ /etc/passwd
- -号表示左对齐
awk -F : ‘{printf "Username: %-15s,UDI %d \n",$1,$3}‘ /etc/passwd
+:显示数值的符号
4、操作符
算术运算操作符
x+y,x-y,x*y,x/y,x%y
-x 取反
+x 把字符转换为数值
字符串操作符:没有符号的操作符,字符串连接
赋值操作符
=,+=,-=,*=,/=,%=,^=,++,--
比较操作符
>,>=,<.<=,!=,==
模式匹配符:
~:左侧字符串是否表示匹配右侧字符串
!~表示不匹配
逻辑操作符:
&&
||
!
函数调用:
function_name(arguments1,arguments2...)
条件表达式:
selector ? if-true-expression: if-false-expression
awk -F: ‘{$3>=1000?usertype="Commen User":usertype="Systemadmin or Sysuser";printf"%15s:%-s\n",$1,usertype}‘ /etc/passwd
5、PATTERN
实现地址定界的功能
(1)empty:空模式,匹配每一行
(2)/regular expression/: 正则表达式
awk ‘!/^UUID/{print $1}‘ /etc/fstab
awk ‘!/^UUID/{print $1}‘ /etc/fstab
(3)关系表达式:relational expression:关系表达式:关系表达式:结果有“真”有"假“结果非0值为真。
awk -F : ‘$NF=="/bin/bash"{print $1,$NF}‘ /etc/passwd
awk -F : ‘$NF~/bash$/{print $1,$NF}‘ /etc/passwd
(4)lin ranges:行范围 地址定界
awk -F : ‘/^root/,/^tcpdump/{print $1}‘ /etc/passwd
awk -F : ‘/^root/,/^tcpdump/{print $1}‘ /etc/passwd
awk -F : ‘(NR>=2&&NR<=10){print $1}‘ /etc/passwd
不支持直接给出数字的格式,可以用变量来限制行范围
(5)BEGIN/END模式
BEGIN{}:仅在开始处理文件中的文本之前执行一次;
END{}:仅在文本处理完成之后执行一次;
awk -F: ‘BEGIN{print " username uid \n-----------------------------"} {print $1,$3} END{print"=========== \n end"}‘ /etc/passwd
6常用的action
(1)Expressions
(2) Control statements: if while 等
(3)Compound statements:组合语句
(4)input statements
(5) output statements
7控制语句
(1)if if(conditons){statments}
if(conditions){statments}else{statments}
(2)while(condition){statments}
(3)do statments}
(4) for(expr1;expr2;expr3){statements}
break
continue
delete array [index]
delete array
exit
{statements} 多个语句语句是需要用花括号括起来的
7.1 if-else{statments}
语法 if(condition)statement[else statement]
某个用户的id号大于1000
awk -F: ‘{if($3>=1000){ printf"commen user:%s\n ",$1} else {printf "root or Sysuser %s \n ",$1} }‘ /etc/passwd
使用场景:对awk取得的整行或某个字段做条件判断:
awk -F: ‘{if($NF=="/bin/bash") print $1}‘ /etc/passwd
awk ‘{if(NF>5) print $0}‘ /etc/fstab
7.2 while 循环
语法:while(condition) statement
条件为”真“,进入循环;条件为假,退出循环;
使用场景 :对一行内的多个字段 逐一类似处理时使用:对数组中的各元素逐一处理时使用
显示这个字段
lenth()
awk ‘/^[[:space:]]*linux16/{print}‘ /etc/grub2.cfg
awk ‘/^[[:space:]]*linux16/{i=1;while(i<NF){print $i,length($i);i++}}‘ /etc/grub2.cfg
awk ‘/^[[:space:]]*linux16/{i=1;while(i<NF){if(length($i)>=7){print $i,length($i)};i++}}‘ /etc/grub2.cfg
7.3 do-while循环
语法
do statement while(condition)
意义:至少执行一次循环体
7.4 for(expr1;expr2;expr3) statement
for(variable assignment;condition;internation process){for-body}
awk ‘/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}‘ /etc/grub2.cfg
特殊用法
能够遍历数组中的元素
for(var in array) {for-body}
7.5 swithc 语句
语法 switch(expression){case VALUE1 or /REGEXP/ :statement;case VALUE2 or/REGEXP2/:statement....;default statement}
7.6 break和continue
break[n] 退出n轮循环
continue
7.7 next 提前结束对本行的处理,而直接进入下一行:
awk -F: ‘{if($3%2!=0) next; print $1,$3}‘ /etc/passwd
8、array 数组 -连续的内存空间,分为两类 一、数字索引的数组 二、关联数组
array[index-expression]
index-expression:
(1)可以使用任意字符串 字符串要使用双引号
(2)如果某数组元素事先不存在,在引用时awk会自动创建此元素,并将其值初始化为空串
若要判断数组中是否存在某元素,要使用”index in array"格式进行
weekdays[mon]=monday
awk ‘BEGIN{weekdays[mon]="monday";weekdays[tue]="tuesday";print weekdays[mon]}‘
awk ‘BEGIN{weekdays["mo"n]="monday";weekdays["tue"]="tuesday";print weekdays["mo"n]}‘
awk ‘BEGIN{weekdays["mo"n]="monday";weekdays["tue"]="tuesday";print weekdays["mo"n]}‘
awk ‘BEGIN{weekdays["mo"n]="monday";weekdays["tue"]="tuesday";print weekdays["tue"]}‘
awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays) print weekdays[i]}‘
若要遍历数组中的每个元素,要使用for循环:
for(var in array) {for-body}
注意:var会遍历array的每个索引
awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays) print weekdays[i]}‘
netstat -tan
state["LISTEN"]++
state["ESTABLISHED"]++
netstat -tan|awk ‘/^tcp\>/{state[$NF]++}END{for(i in state ){print i ,state[i]}}‘
ss -tan
awk ‘{ip[$1]++}END{for( i in ip){print i,ip[i]}}‘ /var/log/httpd/access_log
统计ip访问网站的次数
练习题 统计/etc/fstab中每个单词出现的次数
awk ‘!/^#/{fs[$3]++}END{for(i in fs){print i,fs[i]}}‘ /etc/fstab
awk ‘/^UUDI/{fs[$3]++}END{for(i in fs){print i,fs[i]}}‘ /etc/fstab
统计/etc/fstab中每个文件类型出在的次数
awk ‘{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}‘ /etc/fstab
9内置函数
9.1内置函数
数值处理
rand():返回一个0和1之间的小数 只有第一次取的是随机的,后面的数字都是同一个
sin()
cos()
字符串处理的 length() 返回指定字符串的长度
sub(r,s,[t]);以r表示的模式查找t所表示的字符的字符中匹配的内容,并将第一次出现替换为s所表示的内容:
gsub()表示全局替换以r表示的模式查找t所表示的字符的字符中匹配的内容,并将所有出下替换为s所表示的内容
split(s,a[,r])以r为分隔符,切割字符串s,并将切割后的结果保存至a所表示的数组中;
推荐看 sed和awk
awk学习随常记录