首页 > 代码库 > 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学习随常记录