Linux下的awk使用

awk介绍

Awk 是一种编程语言,主要用于linux/unix下对文本和数据进行扫描处理,数据可以来自标准输入,文件和管道,拥有众多的发行版本,awk,nawk,gawk,MKS awk, tawk, 最常用的是mawk,gawk

rhel系统默认的是 gawk;ubuntu系列产品用mawk

 awk 工作流程

awk基本结构由模式匹配和处理过程(动作)组成,pattern+action

首先对文件进行逐行扫描,从第一行到最后一行,逐行进行匹配特定模式的行,并在这些行上进行用户想要的操作。在读取文件每一行时,判断是否与给定的模式相匹配,如果匹配,则执行处理过程,否则不做任何操作;如果没有指定的脚本,则把匹配的行标准输出,默认处理动作为print打印;如果没有指定模式匹配,则默认匹配所有数据。

awk有两个特殊模式:BEGIN和END ,被放置在没有读取任何数据之前以及在所有数据读取完之后执行。

awk的基础语法

awk [选项]  ‘{[pattern] + action}' [filenames]

选项

-F fs, 指定fs为输入行的分隔符,默认的分隔符为空格或者制表符

-v var=val , 在处理动作之前,设置一个变量var,值为val

-f program-fle   ,从脚本中读取awk指令,以取代在命令参数中输入脚本 

-W compat  ,使用兼容模式运行awk,GUN拓展选项将被忽略 

-W dump-variables[=file] , 打印全局变量到文件中 

awk 程序语法结构:一个awk程序包含一系列的模式(动作指令)或者函数,定义模式可以使用BEGIN/END/表达式 ,用来限定操作对象的多个表达式使用逗号隔开,动作指令使用{}括起来

 

一、awk操作指令

1. 内置变量

变量名          描述

ARGC          命令行参数个数
FILENAME   当前输入文档的名称
FNR             当前输入文档的记录编号,多个输入文档时有用
NR               输入流当前记录编号
NF               当前记录的字段个数
FS          字段分割符
OFS       输出字段分割符,默认空格
ORS      输出记录分隔符,默认换行符\n
RS      输入记录分隔符,默认换行符

打印当前文档的当前编号,两个文件是分开的

[root@centos7 ~]# awk '{print FNR}' awktest.txt test.txt

awk将两个文件作为一个整体输入流,通过NR输入当前编号

[root@centos7 ~]# awk '{print NR}' awktest.txt test.txt

通过OFS将输出分隔符设置为‘_’

[root@centos7 ~]# echo hello the wold |awk 'BEGIN {OFS="_"} {print $1,$2,$3}'

>>hello_the_wold

读取输入输出,以空白行为分隔符

[root@centos7 ~]# awk 'BEGIN {FS="\n";RS=""} {print $1}' awktest.txt

2. 记录与字段

awk 一次从文件中读取一条记录,并将记录存储在字段变量$0中,记录被分割为字段存储在$1,$2,$3......$NF 中(分隔符默认为空格或制表符)

输出第一个和最后一个字段

[root@centos7 ~]# echo hello the wold |awk '{print $1,$NF}'

>>hello wold

3. 分隔符

输出以t为分割符的最后一个字段

[root@centos7 ~]# echo hello the wold |awk -F"t" '{print $NF}'

[root@centos7 ~]# echo hello the wold |awk 'BEGIN {FS="t"} {print $NF}'

>>he wold

多个分隔符,输出以t 和w 分割的第一和最后一个字段

[root@centos7 ~]# echo hello the wold |awk -F"[t,w]" '{print $1,$NF}'

>>hello old

4. 表达式

表达式 由变量,常量,正则表达式,操作符组成

awk中变量有字符和数字常量,如果在awk中定义变量没有初始化,则初始化值为空字符或0,字符操作一定要加引号

同python中的表达式都差不多,大于小于等于,小于等于,++,-- .....

~  匹配

!~  不匹配

||  或

&& 与

[root@centos7 ~]# echo hello |awk 'x=1,y=2 {print x*2,y*3}'

>>2 6

统计空白行数

[root@centos7 ~]# awk '/^$/ {x+=1} END{print x}' awktest.txt

打印root用户的uid号

[root@centos7 ~]# awk -F":" '$1~/root/ {print $3}' /etc/passwd

0

[root@centos7 ~]# awk -F: '$1~/root/ {print $3}' /etc/passwd

0

打印用户uid大于500的用户

[root@centos7 ~]# awk -F: '$3>500  {print $1}' /etc/passwd

 

二、awk中的循环语句

1. if 语句

格式:

if(表达式) 动作1 ;else 动作2

例子:

打印 磁盘中boot下的可使用值,小于1000  打印ERROR,否则打印OK

[root@centos7 ~]# df |grep boot|awk '{if($4<1000) print "ERROR";else print "OK"}'

>>OK

2 . while 语句

格式1:

while(条件){动作1;动作2}

[root@centos7 ~]# awk ' BEGIN {while(i<5){print i ;i++}}'

格式2:

do {动作}  while (条件)

[root@centos7 ~]# awk ' BEGIN {do{print i;i++}while(i<5)}'

[root@centos7 ~]# echo hello| awk '{i=2;while(i<5){print i ;i++}}'

[root@centos7 ~]# awk -F: '$1~/root/{i=1;while(i<=NF){print i $i;i++}}' /etc/passwd

1root

2x

30

40

5root

6/root

7/bin/bash

3. for 语句

格式:

for(变量;条件;计数器) { 动作}

[root@centos7 ~]# echo hello|awk '{for(i=1;i<5;i++){print i}}'

统计/etc/passwd 下$7的个数

[root@centos7 ~]# # awk -F: '{a[$7]++}END{for(i in a){if(i !="") print i":"a[i]}}' /etc/passwd

/bin/sync:1

/bin/bash:2

/sbin/nologin:38

/sbin/halt:1

/sbin/shutdown:1

4. continue 和break

[root@centos7 ~]# echo hello |awk '{for(i=1;i<5;i++){if(i==3) break;print i}}'

1

2

[root@centos7 ~]# echo hello |awk '{for(i=1;i<5;i++){if(i==3) continue;print i}}'

1

2

4

三、awk中的函数

1. rand()函数

随机产生一个0-1之间的浮点数,需要和srand() 配合使用,否则产生的rand()随机数都相同

[root@centos7 ~]# echo hello|awk '{srand();print rand()}'

2. gsub(x,y,z)函数  --全局替换

替换函数: x替换为y ,z为字串,默认是$0

在字串z中使用字符y替换 正则表达式x匹配的字串

[root@centos7 ~]# awk 'gsub(/is/,"are",$0){print $0}' awktest.txt

3. sub(x,y,z)函数   --替换第一个

替换函数: x替换为y ,z为字串,默认是$0

在字串z中使用字符y替换 正则表达式x匹配的第一个字串

[root@centos7 ~]# awk 'sub(/is/,"are",$0){print $0}' awktest.txt

gsub 相当于sed中的 s///g

sub 想当于 sed中的s///

4. length(z)函数

返回字串z的长度

[root@centos7 ~]# awk '{print length(z)}' awktest.txt

5. getline 函数

从输入中读取下一行内容

[root@centos7 ~]#

df -h |awk 'BEGIN{print "DISK FREE"}{if(NF==1){getline;print $3};if(NF==6){print $4}}'

DISK FREE

可用

5.7G

471M

487M

478M

487M

223M

4.0G

98M

98M

 

 

 

posted @ 2020-07-16 22:19  BackingStar  阅读(239)  评论(0编辑  收藏  举报