漫漫运维路——文本处理三剑客之awk基础


awkgawk,是一款在Linux中实现文本格式化输出的文本处理工具,在Linux中与文本过滤工具grep和文本行编辑器sed共同组成Linux中的文本处理三剑客。

awk在处理文本时以行为单位,读入整行数据后以指定的分隔符对行进行切片,然后再针对切片后的数据进行处理。如下图所示:

 

wKioL1VggbKTc9pqAADdSymVeG4763.jpg

 

文本经过指定的分隔符进行切片后再对每一片进行处理,然后在根据设定的动作对处理后的文本执行动作,而切片后的文本如果只想引用一部分也可以使用变量进行引用,其引用的各个变量如下表所示:

变量

指代

$0$N

当前处理行的所有内容

$1,$2$3...

当前处理行切片后的第一、第二、第三...片内容

 

awk使用方式

1.awk命令行

#awk 

2.awk程序文件

awk -f /PATH/TO/awk_script_file

3.awk脚本

#/bin/awk -f

awk基本基本语法

awk  [OPTIONS] program FILE1 FILE2......

ProgramPATTERN{ACTION STATEMENT}

Program由语句组成,各语句之间使用;隔开

OPTIONS

-F:指定分隔符

例:显示当前系统的各用户名及其UID

[root@localhost tmp]# awk -F: '{print $1,$3}' /etc/passwd


-v:指定变量

例:使用awk定义一个变量,并显示其值

[root@localhost tmp]# awk -v file=/etc/passwd BEGIN'{print file}'


/etc/passwd

-f:后接awk脚本文件

例:

awk内置变量:

变量

意义

变量

作用

FS

输入分隔符

OFS

输出分隔符

RS

行分隔符

NR

文件的行数(统一计数)

NF

当前行的字段数

FNR

文件的行数(单独计数)

FILENAME

当前处理文件的文件名

ARGC

当前命令行参数的个数

ARGV

以数组方式保存命令行参数个数



变量的几个使用实例

1:使用多种字符作为输入分隔符


wKiom1VggFuAneKVAAE-LWmJ0XA314.jpg

 

2:使用不同的输出分隔符


wKiom1VggHLBNJW1AACgOBOxha8800.jpg

 


3:使用“,”作为行分隔符


wKioL1VgghnQxwiFAACONKdJ_fs161.jpg

 


4:查看当前文件每行的字段数


wKioL1VggjeQYqLFAAD3ceUjDhU668.jpg

 


5:使用分别计数和统一计数显示当前处理的文件和正处理的行数,并显示其文件名


wKiom1VggNXz32yGAAD0urQWyHM299.jpg

 


6:显示当前命令的参数个数

[root@localhost tmp]# awk 'BEGIN{print ARGC}'
1


ACTIONprintprintf

EXPRESSIONS:表达式

Control Statements:控制语句

if condition{statements} [else {statement}]

例:打印指定文件的行,条件为其字段数必须大于三


wKioL1VggpWgUeavAACpJLelme0135.jpg

 

while (condition) {statements}

例:显示指定文件中单词长度大于5的字符串


wKiom1VggV_QCuN6AACpOp2L9Qc463.jpg


do statement while condition) 

for expr1expr2expr3{statements}

for var in array{statements}:遍历数组array中的元素

break 

语法:break [n]:表示退出n轮循环

continue 

exit [expression]

{statements}

next:执行next会跳过当前动作,进入下一轮

例:找出当前系统上所有UID为偶数的用户,并显示其用户名和UID


wKiom1VggYizCYdZAACudb2x3fE893.jpg

  

Compound Statements:复合语句

Input statements:输入语句

Output statements:输出语句

print:直接打印输出内容,会自动换行,上面已经有例子

print item1item2... 

printf:格式化打印输出指定内容,不会自动换行

printf  FORMAT [修饰符]item1item2,......

FORMAT

%c:只显示字符的ASCII

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

%f:显示浮点数

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

%s:显示字符串

%u:显示无符号整数

%%:显示%本身

修饰符:

#[#]

+:显示数值符号

-:左对齐

格式化输出的一个实例

例:格式化输出当前系统的用户和其ID

[root@localhost tmp]# awk -F":" '{printf "%s\n %s %15-s %s %2-4s %s\n","---------------------------","|",$1,"|",$3,"|"}' /etc/passwd


wKioL1Vgg9WBSyxbAAEAhqPtUHA703.jpg


awk中的操作符

算数操作符:

操作符

意义

操作符

意义

x+y

xy

-x

表示x是个负值

x-y

xy

x%y

xy取模

x*y

xy

x^y

xy次方

x/y

xy



例:定义两个变量,计算两个变量的和

[root@localhost tmp]# awk -v f1=2 -v f2=3 'BEGIN{print f1+f2}'

字符操作符:

字符连接,可直接写,不使用其他符号,

赋值操作符:

操作符

意义

操作符

意义

=

直接赋值

%=

取模后赋值

+=

加后赋值

^=

次方后赋值

-=

减后赋值

--

自减1后赋值

*=

乘后赋值

++

自加1后赋值

/=

除后赋值



例:定义一个变量,然后对变量进行自加后打印出来

[root@localhost tmp]# awk -v test=1 'BEGIN{test++;print test}'


比较操作符:

操作符

意义

>

前面变量是否大于后面变量

>=

前面变量是否大于或者等于后面变量

<

前面变量是否小于后面变量

<=

前面变量是否小于或等于后面变量

==

比较前后两个变量是否等值

!=

比较前后连个变量是否不等

例:定义两个变量并赋值,判断其是否相等

[root@localhost tmp]# awk -v f1=2 -v f2=3 'BEGIN{print f1==f2}'
1


 模式匹配操作符

操作符

意义

~

是否能被右侧模式所匹配

~

是否不能被右侧模式所匹配

例:查看当前系统上所有用户的用户名有哪些是以r开头的

[root@localhost tmp]# awk -F: '{print "user:"$1,"T/F:",$1~/^r.*/}' /etc/passwd


wKiom1Vggv-xvav_AAFMmJXm48Y476.jpg

 

逻辑操作符

操作符

意义

&&

与运算

||

或运算

非运算

 

例:判断给定文件中是否包含root字符串或第一和第二个字符串是否为都为tom,1为是,0为否

[root@localhost tmp]# awk -F" " '{print NR,($1=="root" || $2=="root" ||$1==$2 && $1=="tom") }' awk


wKioL1VghLXRoWX-AADFCgeJOiM292.jpg

 

条件表达式:

selectorIf-ture-expressionif-false-expression

例:判断当前系统上的各个账号的类型(系统账号和普通账号)

[root@localhost tmp]# awk -F: '$3<500?utype="system user":utype="common user"{print $1,":",utype}' /etc/passwd


wKioL1VghdiwlG2pAAFWGAxo6mw999.jpg

 

函数调用:

function_nameargu1argu2...

常见内建函数

land():返回0,1随机数

length():取字符串长度

subrs[t]):基于r所表示的模式来匹配字符串t中的内容,将其第一次被匹配到的内容替换为s所表示的字符串

gsubrs[t]):同上,只不过是全局替换

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

substrsin):从s所表示的字符串取子串,取法:从i表示的位置开始,取n个字符

systime():取当前系统的时间戳

用户自定义函数

Function f_namep,q{...}

 

PATTERN

空模式:匹配文本中的所有行

/Regular Expression/:仅将ACTION应用于Regular Expression所匹配到的行

例:显示/etc/passwd文件中包含root字符串行的相关信息

[root@localhost tmp]# awk '/root/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin


关系表达式:结果为真时才执行

例:找出/etc/passwd文件中的普通用户,并打印输出

[root@localhost tmp]# awk -F: '$3>=500{print $1,$3}' /etc/passwd
wuxiaotao 500
wxt 501


行定界:start_linestop_line

BEGIN:在文件格式化操作之前实现执行的一次操作

例:打印欢迎信息

[root@localhost tmp]# awk 'BEGIN{print "hello welcome!"}'


END:在文件格式化操作完成后,命令退出之前执行的一次操作

例:处理完文件后提示文件已经处理完了

[root@localhost tmp]# awk -F: '$3>=500{print $1,$3}END{print "The End"}' /etc/passwd
wuxiaotao 500
wxt 501
The End


数组:

关联数组:array[index-expression]

Index-expression

可以使用任意字符

如果某数组事先不存在,则在引用时,awk会自动创建此元素将其值初始化为空串

例:统计给定文件中各个单词的出现次数

[root@localhost tmp]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(j in count){print j,count[j]}}' awk 


wKioL1VghaHB87OYAAEQp1oANx0575.jpg

 

例:查看当前tcp协议的各种状态的个数

[root@localhost tmp]# ss -tan | awk '!/state/{state[$1]++}END{for(i in state)print i,state[i]}'

wKiom1Vgg_ijqi2gAAChA7ZKecY934.jpg

 

例:统计当前服务器上各个ip访问的次数

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

 差不多就这样吧,内容太多了,很多格式也不统一,有些都是上课跟着老师做的笔记。惭愧!

 

 

 

 

 

 

 

 

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章