awk

一、awk简介

 

一次读取一行文本,按输入分隔符进行切片,切成多个组成部分,将每片直接保存在内建的变量中,$1,$2,$3....,引用指定的变量,可以显示指定断,或者多个断。如果需要显示全部的,需要使用$0来引用。可以对单个片断进行判断,也可以对所有断进行循环判断。其默认分隔符为空格

 

gawk - pattern scanning and processing language

 

基本用法:gawk [options] 'program' FILE ...

program: PATTERN{ACTION STATEMENTS}

语句之间用分号分隔

 

print, printf

 

选项:

-F:指明输入时用到的字段分隔符;

-v var=value: 自定义变量;

 

二、awk用法的简要介绍


第一种模式

awk [options] 'scripts' file1,file2.....

在这种模式中,scripts主要是命令的堆砌,对输入的文本行进行处理,通过命令print,printf或是输出重定向的方式显示出来,这里经常用到的知识点是:awk的内置变量,以及命令print和printf的使用

 

第二种模式

awk [options] 'PATTERN{action}' file,file2.....

在这种模式中,最重要的是5种模式和5种action的使用,以及awk的数组的使用和内置函数

 

1、print

print item1, item2, ...

要点

(1) 逗号分隔符;

(2)输出的各item可以字符串,也可以是数值;当前记录的字段、变量或awk的表达式;

(3)如省略item,相当于print $0;

 

2、变量

2.1内建变量

(1)FS:input field seperator,默认为空白字符;

(2)OFS:output field seperator,默认为空白字符;

(3)RS:input record seperator,输入时的换行符;

(4)ORS:output record seperator,输出时的换行符;

(5)NF:number of field,字段数量

{print NF}, {print $NF}

(6)NR:number of record, 行数;

(7)FNR:各文件分别计数;行数;

(8)FILENAME:当前文件名;

(9)ARGC:命令行参数的个数;

ARGV:数组,保存的是命令行所给定的各参数;

 

2.2自定义变量

(1) -v var=value

变量名区分字符大小写;

(2) 在program中直接定义

 

3、printf命令

格式化输出:printf FORMAT, item1, item2, ...

 

(1) FORMAT必须给出;

(2) 不会自动换行,需要显式给出换行控制符,\n

(3) FORMAT中需要分别为后面的每个item指定一个格式化符号;

 

(1)格式符:

%c: 显示字符的ASCII码;

%d, %i: 显示十进制整数;

%e, %E: 科学计数法数值显示;

%f:显示为浮点数;

%g, %G:以科学计数法或浮点形式显示数值;

%s:显示字符串;

%u:无符号整数;

%%: 显示%自身;

 

格式符:

(a)%s:显示字符串;

(b)%d, %i: 显示十进制整数;

 

(2)修饰符:

#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度;

%3.1f

-: 左对齐

+:显示数值的符号

-:左对齐

 

4、操作符

 

(1)算术操作符:

x+y, x-y, x*y, x/y, x^y, x%y

-x

+x: 转换为数值;

 

字符串操作符:没有符号的操作符,字符串连接

 

(2)赋值操作符:

=, +=, -=, *=, /=, %=, ^=

++, --

 

(3)比较操作符:

>, >=, <, <=, !=, ==

 

(4)模式匹配符:

~:是否匹配

!~:是否不匹配

 

(5)逻辑操作符:

&&

||

!

 

(6)函数调用:

function_name(argu1, argu2, ...)

 

(7)条件表达式:

selector?if-true-expression:if-false-expression

 

示例:显示/etc/passwd 中的系统用户和普通用户

ID>1000 普通用户,<1000系统用户

 

5、PATTERN

(1) empty:空模式,匹配每一行;

 

(2) /regular expression/:仅处理能够被此处的模式匹配到的行;

(3) relational expression:

关系表达式;结果有“真”有“假”;结果为“真”才会被处理;

真:结果为非0值,非空字符串;

显示普通用户

找出那个用户用户名是/bin/

(4) line ranges:行范围,

(5) BEGIN/END模式

 

6、常用的action

 

(1) Expressions

(2) Control statements:if, while等;

(3) Compound statements:组合语句;

(4) input statements

(5) output statements

 

7、控制语句

 

if(condition) {statments}

if(condition) {statments} else {statements}

while(conditon) {statments}

do {statements} while(condition)

for(expr1;expr2;expr3) {statements}

break

continue

delete array[index]

delete array

exit

{ statements }

7.1 if-else

 

语法:if(condition) statement [else statement]

 

用户名大于等于1000输出普通用户,否则输出超级用户

~]# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd

 

输出字符结尾为/bin/bash的用户名

~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd

 

输出空白字符做分隔,空白字符大于5个的行

~]# awk '{if(NF>5) print $0}' /etc/fstab

 

输出系统占用系统空间大于20%的文件系统名

~]# df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=20) print $1}'

使用场景:对awk取得的整行或某个字段做条件判断;

 

7.2 while循环

语法:while(condition) statement

条件“真”,进入循环;条件“假”,退出循环;

 

使用场景:对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用;

 

输出/etc/grub2.cfg中各个字段名以及该字段的长度

~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg

 

输出/etc/grub2.cfg中各个字段名以及该字段长度大于7的行

~]# 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循环

语法:for(expr1;expr2;expr3) statement

 

for(variable assignment;condition;iteration 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 switch语句

语法:switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; ...; default: statement}

 

7.6 break和continue

break [n]

continue

 

7.7 next

 

提前结束对本行的处理而直接进入下一行;

 

输出UID为偶数的行的用户名

~]# 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"

 

若要遍历数组中的每个元素,要使用for循环;

for(var in array) {for-body}

 

~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}'

 

注意:var会遍历array的每个索引;

state["LISTEN"]++

state["ESTABLISHED"]++

 

统计natstate -tan 各个状态出现了多少次

~]# netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}'

 

显示在accesslog中IP出现个数

~]# awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log

 

练习1:统计/etc/fstab文件中每个文件系统类型出现的次数;

~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab

 

练习2:统计指定文件中每个单词出现的次数;

~]# 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之间一个随机数;

 

字符串处理:

length([s]):返回指定字符串的长度;

sub(r,s,[t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其第一次出现替换为s所表示的内容;

gsub(r,s,[t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其所有出现均替换为s所表示的内容;

split(s,a[,r]):以r为分隔符切割字符s,并将切割后的结果保存至a所表示的数组中;

 

~]# netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'

 

 

9.2 自定义函数

《sed和awk》

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值