shell编程之awk(数据筛选与处理)(代码片段)

锦衣admin 锦衣admin     2022-11-29     484

关键词:

shell编程之awk(数据筛选与处理)

awk 命令介绍

常见的数据分析:

  • 数据数据收集:负责数据的收集

  • 数据清洗:负责数据的筛选

  • 数据分析:数据运算、整理

  • 数据展示:图表或表格方式输出结果

shell脚本数据的处理 :

  1. 数据检索:grep、tr、cut
  2. 数据处理:uniq、sort、tee、paste、xargs

之前的脚本都是通过grep、tr、cut、uniq、sort、tee、paste、xargs等命令通过管道组合在一起将字符串检索出来的,然后通过shell中对应的运算得到结果,在数据检索过程中操作比较繁琐

awk介绍:

在日常计算机管理中,总有很多数据输出到屏幕或文件中,这些数据包含了标准输出、标准错误输出。默认情况下,这些信息全部输出到默认输出设备(屏幕)。这些数据只有一小部分是需要重点关注的。我们要把关注的信息通过过滤或者提取以备后续调用。早先的学习中(grep来过滤数据、cut和tr提出某些字段),但它们都不具备提取并处理数据的能力,都必须先过滤,再提取转存到内存中,然后通过变量提取去处理。比如:

内存使用率的统计步骤:

  1. 通过free -m 提取成内存总量,赋值给变量memory_totle

  2. 通过free -m 提取出n内存使用量,赋值给变量memory_use

  3. 通过数学运算计算内存使用率

操作过于繁琐,需要执行多步才能得到内存使用率,而awk命令能够集过滤、提取、运算为一体

awk命令可以从输出流中检索自己需要的数据,而不需要向以前一样通过大量命令组合检索。只需要一个awk命令就能完成,并且还能够通过awk对数据进行处理,而不需要额外的shell运算

awk命令是一种可以处理数据、产生格式化报表的语言,功能十分强大。awk认为文件中的每一行都是一条记录,记录与记录的分隔符为换行符每一列都是一个字段,字段与字段的分隔符默认是一个或多个空格或tab制表符

awk的工作是读取数据,将每一行数据视为一条记录,每条记录以字段分隔符划分若干个字段,然后输出各字段的值

awk的平行命令还有:gawk、pgawk、dgawk

总结: awk 是行编辑器,负责数据的截取和处理

awk 语法

语法格式:
#	awk [option] [BEGIN]pogram[END][filename]
		常用options选项:
			-F :指定描绘一行中数据字段的文件分隔符,默认为空格(即指定行的分隔符)
			-f file:指定读取程序的文件名,就是将awk的命令放到文本中用-f选项调用
			-v var=value:定义awk程序中使用的变量和默认值

#l	注意:awk程序脚本由左大括号和有大括号定义。脚本命令必须放置在两个大括号之间。
#l	     由于awk命令假定脚本是单文本字符串,所以必须将脚本包括在单引号内

#awk程序运行优先级是:
	1"BENGIN":在开始处理数据流前执行,可选项
	2"program":如何处理数据流,必选项
	3"END":处理完数据流后执行,可选项

awk 的基本应用

awk 对字段(列)的提取

字段提取: 提取一个文本中的一列数据并打印输出
用逗号,分隔字段内置变量打印

字段相关内置变量:

  • $0:表示整行文本
  • $1:表示文本行中的第一个数据字段
  • $2:表示文本行中的第二个数据字段
  • $N:表示文本行中的第N个数据字段
  • $NF:表示文本行中的最后一个数据字段
[root@server ~]# cat awk_column
	 1 This little sister is my dish
	 2 This little sister is my dish
	 3 This little sister is my dish
	root:x:0:0:root:/root:/bin/bash
	bin:x:1:1:bin:/bin:/sbin/nologin

#l 提取列(第一列)
[root@server ~]# awk 'print $1' awk_column
1
2
3
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

#l 提取列(第二列)
	[root@server ~]# awk 'print $2' awk_column
		This
		This
		This
		//这是打印的空行
		//这是打印的空行

#l 指定分隔符提取列(第二列)
	[root@server ~]# awk -F ":" 'print $2' awk_column
		//这是打印的空行
		//这是打印的空行		
		//这是打印的空行			
		x
		x

#l 打印第13列数据
	[root@server ~]# awk 'print $1,$3' awk_column
		1 little
		2 little
		3 little
		root:x:0:0:root:/root:/bin/bash
		bin:x:1:1:bin:/bin:/sbin/nologin

#l 打印第1列和最后一列数据
	[root@server ~]# awk 'print $1,$NF' awk_column	=>	第四五行只有一列,所以第一列和最后一列都是它自身
		1 dish
		2 dish
		3 dish
		root:x:0:0:root:/root:/bin/bash root:x:0:0:root:/root:/bin/bash
		bin:x:1:1:bin:/bin:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin

awk 对记录(行)的提取

记录提取: 提取一个文本的一行并打印输出

用逗号,分隔行号打印;NR==1,NR==3:打印1至3行
用冒号;分割行号awk程序;NR==1,NR==3:打印1和3行

记录的提取方法有两种:通过行号提取通过正则匹配

记录相关内置变量:

  • NR==N:指定行号N
[root@server ~]# cat awk_column
	 1 This little sister is my dish
	 2 This little sister is my dish
	 3 This little sister is my dish
	root:x:0:0:root:/root:/bin/bash
	bin:x:1:1:bin:/bin:/sbin/nologin


#l 提取行全部数据(第四行)
	[root@server ~]# awk 'NR==4print $0' awk_column
		root:x:0:0:root:/root:/bin/bash

#l 提取第四行第5个字段,-F 指定分隔符 ":"
	[root@server ~]# awk -F ":" 'NR==4print $5' awk_column
		root

#l 同时打印多列(第二行34列)
	[root@server ~]# awk 'NR==2print $3,$4' awk_column
		little sister

#L 打印多行,同时可以指定输出列的位置。(NR==1,NR==3:代表13行)		=>	, 逗号分隔行号
	[root@server ~]# awk 'NR==1,NR==3print $6,$3,$4' awk_column
		my little sister
		my little sister
		my little sister

#l	打印多行,分割awk程序											=>	;	冒号分割
[root@server ~]# awk 'NR==3;NR==3print $1,$6,$3,$4' awk_column
	 3 This little sister is my dish
	3 my little sister

awk 程序的优先级

关于awk程序执行的优先级,BEGIN是优先级最高的代码块,是在执行program之前执行,不需要提供数据源,因为不涉及到任何数据的处理,也不依赖于program代码块

program是对数据流操作,是必选代码块,也是默认代码块。所以在执行时必须提供数据源

END是处理完数据流后的操作,如果需要执行END代码块,就必须需要program的支持,单个无法执行

BEGIN 说明:

#l 不需要数据源就可以执行:
	[root@server ~]# awk 'BEGINprint "hello"'
		hello

程序优先级说明:

  • program需要数据源,END需要program处理后的数据源
[root@server ~]# awk 'ENDprint "end========"print $0BEGINprint "start========"' awk_column
	start========
	 1 This little sister is my dish
	 2 This little sister is my dish
	 3 This little sister is my dish
	root:x:0:0:root:/root:/bin/bash
	bin:x:1:1:bin:/bin:/sbin/nologin
	end========

#l 备注:会优先执行BEGIN的内容,然后是program,再然后是END的内容

程序优先级总结:

BEGIN:处理数据源之前干什么,不需要数据源就可以执行
program:对数据源干什么,需要数据源(截取和运算)
END:对数据源处理后干什么,需要数据源

awk 高级应用

awk 是一本语言,那么就会符合语言的特性,除了可以定义变量外、还可以定义数组、还可以进行计算、还可以流程控制

-F命令选项

  • 重新指定默认分隔符空格,并将-F指定的分隔符删除打印
  • 内置变量如果不加逗号,隔开-F不会使用空格分隔符
#l	以冒号:为分割符打印13,最后一个字段,默认以空格为分隔符打印
	[root@server ~]# awk -F ":" 'NR==1print $1,$5,$NF' /etc/passwd
		root root /bin/bash

#l	可以通过指定字符串打印
	[root@server ~]# awk -F ":" 'NR==1print $1"-"$5"-"$NF' /etc/passwd
		root-root-/bin/bash
#l	没有逗号,不隔开
	[root@server ~]# awk -F ":" 'NR==1print "uid:"$1"gid:"$5"shell:"$NF' /etc/passwd
		uid:rootgid:rootshell:/bin/bash

#l	逗号隔开列内置变量,打印列时有空格分隔每个字段
	[root@server ~]# awk -F ":" 'NR==1print "uid:"$1,"gid:"$5,"shell:"$NF' /etc/passwd
		uid:root gid:root shell:/bin/bash

awk 定义变量(-v命令)

在程序里面定义变量需要用冒号;分割

#l -v 选项定义一个变量
	[root@server ~]# awk -v name='coco' 'BEGINprint name'
		coco

#l 在BEGIN里面定义变量
	[root@server ~]# awk 'BEGINname="liwen";print name'
		liwen

#l 对数据源中的数据赋值给变量(计算totl-free得到使用的内存量)
	[root@server ~]# head -4 /proc/meminfo	=>	内存会发生变化
		MemTotal:        1863252 kB
		MemFree:          164712 kB
		MemAvailable:     555936 kB
		Buffers:               0 kB
	[root@server ~]# awk 'NR==1t=$2NR==2f=$2;print t,f' /proc/meminfo
		1863252 161420
	[root@server ~]# awk 'NR==1t=$2NR==2f=$2;print (t-f)' /proc/meminfo		=>	总体差不多,因为内存是动态的
		1701628

awk 定义数组

数组定义方式:数组名[索引]=值

  • 定义数组时用冒号;分割
#l 在BEGIN里面定义一个数组,取名a
	[root@server ~]# awk 'BEGINa[0]="干啥子";a[1]=5;print a[0],a[1]'
		干啥子 5

#l 从数据源中将数据取出来赋值给数组,取名b
	[root@server ~]# cat array
		 1 This little sister is my dish
		 2 This little sister is my dish
	[root@server ~]# awk 'NR==2b[0]=$1;b[1]=$4NR==2b[3]=$NF;print b[0],b[1],b[3]' array
		2 sister dish

awk 运算

  • 注意在程序program内是无法进行运算的

awk 比较预算:>、>=、==、<、<=、!=

文件内容:

[root@server ~]# cat num
	1
	2
	3
	4
	5
	6
	7
	8
	9
	10
	aaa

awk 比较运算:(需要数据源的比较方式):

#l 				大于	>
	[root@server ~]# awk '$1>7print $0' num
		8
		9
		10
		aaa

#l				大于等于		>=
	[root@server ~]# awk '$1>=7print $0' num
		7
		8
		9
		10
		aaa
		
#l				等于	==			(注意不要和一个等于赋值搅浑)
	[root@server ~]# awk '$1==3print $0' num
		3

#l				小于	<		(aaa不见了)
	[root@server ~]# awk '$1<3print $0' num
		1
		2

#l				小于等于		<=
	[root@server ~]# awk '$1<=3print $0' num
		1
		2
		3

#l				不等于		!=
	[root@server ~]# awk '$1!="aaa"print $0' num
		1
		2
		3
		4
		5
		6
		7
		8
		9
		10

#l				赋值		=
	[root@server ~]# awk '$1="再见"print $0' num
		再见
		再见
		...全部都改变

awk 比较运算:(不需要数据源的比较方式):

  • 也可以做真假判断
  • 根据返回内容。0代表假,1代表真
#l	小于	
	[root@server awk]# awk 'BEGINprint 3<4'1
	[root@server awk]# awk 'BEGINprint 4<3'0

#l 大于,注意:一个大于相当于覆盖输入 无效
	[root@server awk]# awk 'BEGINprint 4>3'
	[root@server awk]# ll
		total 4
		-rw-r--r-- 1 root root 2 Jun  5 01:09 3	
	[root@server awk]# cat 3
		4

#l	大于等于
	[root@server awk]# awk 'BEGINprint 3>=1'1
	[root@server awk]# awk 'BEGINprint 1>=3'0
	
#l	小于等于
	[root@server awk]# awk 'BEGINprint 4<=5'1
	[root@server awk]# awk 'BEGINprint 5<=4'0

#l	等于等于
	[root@server awk]# awk 'BEGINprint 4==4'1
	[root@server awk]# awk 'BEGINprint 4==3'0

#l	不等于
	[root@server nmap]# awk 'BEGINprint 4!=3'1
	[root@server nmap]# awk 'BEGINprint 4!=4'0


#l	备注:一个等于(=)会报错,大于(>)覆盖输入

awk 数学运算:+、-、*、/、**、%、++、+=、–、-=

  • 默认支持浮点型。小数点精确到后四位
[root@server nmap]# awk 'BEGINprint 2+3'
	5
[root@server nmap]# awk 'BEGINprint 2-3'
	-1
[root@server nmap]# awk 'BEGINprint 2*3'
	6
[root@server ~]# awk 'BEGINprint 100/3'
	33.3333
[root@server ~]# awk 'BEGINprint 1/10000'
	0.0001
[root@server ~]# awk 'BEGINprint 1/100000'
	1e-05
[root@server nmap]# awk 'BEGINprint 4%3'
	1
[root@server nmap]# awk 'BEGINprint 2**3'
	8
[root@server nmap]# awk 'BEGINprint (10.5+5.5)*2/4-1'

	7

#l	++	+=
	[root@server ~]# awk 'BEGINa=1;print ++a'
		2
	[root@server ~]# awk 'BEGINa=1;a+=1;print a'
		2

#l	--	-=
	[root@server ~]# awk 'BEGINa=10;print --a'
		9
	[root@server ~]# awk 'BEGINa=10;;a-=1;print a'
		9

awk 字符串匹配运算:==、!=、~、!~

  • 还可以加入正则进行匹配
#L	精确匹配:	==
	[root@server nmap]# awk -F ":" '$1=="root"print $0' /etc/passwd
		root:x:0:0:root:/root:/bin/bash

	[root@server ~]# awk -F ":" '$1=="ro"print $0' /etc/passwd
		ro:x:1002:1002::/home/ro:/bin/bash



#l	精确不匹配
		[root@server ~]# awk -F ":" '$1!="root"print $0' /etc/passwd
			bin:x:1:1:bin:/bin:/sbin/nologin
			daemon:x:2:2:daemon:/sbin:/sbin/nologin
			adm:x:3:4:adm:/var/adm:/sbin/nologin
			....

#l	模糊匹配:字符为 ~		=>	即第一列有ro字符的匹配出来
		[root@server ~]# awk -F: '$1~"ro"print $0' /etc/passwd
			"ro"ot:x:0:0:root:/root:/bin/bash
			ch"ro"ny:x:992:987::/var/lib/chrony:/sbin/nologin
			set"ro"ubleshoot:x:989:983::/var/lib/setroubleshoot:/sbin/nologin
			ro:x:1002:1002::/home/ro:/bin/bash
	
		[root@server ~]# awk -F: '$1~"^ro"print $0' /etc/passwd		=>	加入正则
			root:x:0:0:root:/root:/bin/bash
			ro:x:1002:1002::/home/ro:/bin/bash



#l	模糊不匹配:字符为 !~		=>	即第一列有ro字符的不匹配
		[root@server ~]# awk -F: '$1!~"ro"print $0' /etc/passwd
			bin:x:1:1:bin:/bin:/sbin/nologin
			daemon:x:2:2:daemon:/sbin:/sbin/nologin
			adm:x:3:4:adm:/var/adm:/sbin/nologin
			lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
			...


#l	逻辑匹配:||,匹配第一列为root和lisi行
[root@server ~]# awk -F ":" '$1=="root"||$1=="lisi"print $0' /etc/passwd
	root:x:0:0:root:/root:/bin/bash
	lisi:x:1001:1001::/home/lisi:/bin/bash

awk 逻辑运算:&&、||

#l	与逻辑运算:全真为真,一假永假
	[root@server ~]# awk 'BEGINprint 2>=1 && 3>=1'1
	[root@server ~]# awk 'BEGINprint 2>=1 && 3<1'0


#l	与逻辑运算:一真永真,全假为假
	[root@server ~]# awk 'BEGINprint 2>=1 || 3<1'1
	[root@server ~]# awk 'BEGINprint 2<=1 || 3<1'0

awk 环境变量

变量描述
FIELDWIDTHS以空格分隔的数字列表,用空格定义每个数据字段的精确宽度
FS输入字段分隔符号,与-F命令类似(数据源的字段分隔符)
OFS输出字段分隔符号,打印时不能打印$0
RS输入记录分隔符号,默认是回车
ORS输出记录分隔符号 ,默认是回车,打印时不能打印$0

FIELDWIDTHS:以空格重新分隔字段

  • 重新定义列宽并打印,注意不可以使用$0打印所有,因为$0是打印本行所有内容,不会打印你定义的字段

  • BEGIN中定义

  • FIELDWIDTHS=“列宽值 列宽值 …”,列宽值代表打印出来的字符数量

  • 如果原文本本来就有空格,这个空格也算一个字符被重新定义

[root@server ~]# awk 'NR==1print $0' /etc/passwd
	root:x:0:0:root:/root:/bin/bash


#l	表示第一列$1的字宽为5,第二列$2的字宽为2,第三列$3的字宽为8。本行没有定义列宽是不打印的
	[root@server ~]# awk 'BEGINFIELDWIDTHS="5 2 8"NR==1print $1,$2,$3' /etc/passwd
		root: x: 0:0:root


#l	提取13行,重新定义列宽
[root@server 查看详情  

shell命令三剑客之awk命令详解,cut命令,linux里记录行踪(操作记录)(代码片段)

...awk里面的数组是关联数组:1.8.1awk里如何使用数组来存放数据?1.8.2awk里如何从数组里取出数据?1.8.3awk里关联数组的理解(难点):1.8.4awk里的关联数组之if判断2.cut命令3.linux里记录行踪(操作记录)的地方1.初识awk命令AWK是一种处... 查看详情

十五awk文本处理(代码片段)

  awk编程语言/数据处理引擎   创造者:Aho、Weinberger、Kernighan基于模式匹配检查输入文本,逐行处理并输出通常用在Shell脚本中,获得指定的数据单独用时,可对文本数据做统计  基本用法  语法... 查看详情

shell编程shell中的流程控制之if语句(代码片段)

系列文章【Shell编程】Shell中的正则表达式【Shell编程】字符截取命令cut、printf命令【Shell编程】字符截取命令awk、sed命令【Shell编程】字符处理命令sort和wc【Shell编程】条件判断目录系列文章单分支if条件语句实例如何提取出来根... 查看详情

shell编程-08-awk(代码片段)

...;,`隔开七、指定多个分隔符:`[]`八、awk脚本编程1if 查看详情

awk原理(代码片段)

LinuxShell编程awk命令JAVA编程Linux学习 2023-04-0408:00 发表于山东收录于合集#awk1个#linux36个概述awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出... 查看详情

awk(代码片段)

一、介绍awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具... 查看详情

shell编程字符处理命令sort和wc(代码片段)

系列文章【Shell编程】Shell中的正则表达式【Shell编程】字符截取命令cut、printf命令【Shell编程】字符截取命令awk、sed命令目录系列文章sort命令实例按照首字母做升序按照首字母做倒序把数值型数据按照字符型来对待进行排序把数... 查看详情

shell编程shell中多分支case条件语句(代码片段)

系列文章【Shell编程】Shell中的正则表达式【Shell编程】字符截取命令cut、printf命令【Shell编程】字符截取命令awk、sed命令【Shell编程】字符处理命令sort和wc【Shell编程】条件判断【Shell编程】Shell中的流程控制之if语句目录系列文章... 查看详情

awk文本处理(代码片段)

一、前言(一)、awk简介  awk是一种编程语言,用于在linux/unix下对文本和数据进行处理,数据可以来自标准输入、一个或多个文件,或其它命令的输出,它支持用户自定义函数和动态正则表达式等先进功能,是llinux/unix下的一个... 查看详情

shell编程awk工具(代码片段)

1.printcoins.txtgold11986USAAmericanEaglegold11968AustriaFranzJosef100Koronasilver101964USAingotgold11956Switzelandingotawk‘print‘coin.txt2.print$x:打印第x列awk‘print$1‘coin.txt用制表键对齐  查看详情

awk(代码片段)

awk独立的编程语言Awk是一种处理结构数据并输出格式化结果的编程语言,Awk是其作者"Aho,Weinberger,Kernighan"的简称。Awk通常被用来进行格式扫描和处理。通过扫描一个或多个文件中的行,查看是否匹配指定的正则表达式,并执行相... 查看详情

awk入门(代码片段)

awk是一门模式匹配的编程语言,因为它的主要功能是用于匹配文本并处理,同时它有一些编程语言才有的语法,例如函数、分支循环语句、变量等等,当然比起我们常见的编程语言,Awk相对比较简单。是一种... 查看详情

awk入门(代码片段)

awk是一门模式匹配的编程语言,因为它的主要功能是用于匹配文本并处理,同时它有一些编程语言才有的语法,例如函数、分支循环语句、变量等等,当然比起我们常见的编程语言,Awk相对比较简单。是一种... 查看详情

文本处理三剑客之awk(代码片段)

...emsp;   BEGIN,END    actionstatements对数据进行处理,放在内指明 & 查看详情

文本处理三剑客之awk(代码片段)

简介awk是一种处理文本文件的语言,是一个强大的文本编辑工具。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分在进行各种分析处理。gawk用法:gawk[options]‘PATTERNACTIONSTATEMENTS‘FILE...  &... 查看详情

shell脚本四剑客之awk详解(代码片段)

文章目录awk的介绍awk能够干什么awk的格式工作原理:记录和域内建变量的用法1.FS2.OFS3.RS4.ORS5.NF6.NRBEGIN和END语句块常见案例1.使用NR行号提取ip2.打印UID小于10的账号名称和UID信息3.数学运算4.AWK打印硬盘设备名称,默认以空... 查看详情

shell脚本四剑客之awk详解(代码片段)

文章目录awk的介绍awk能够干什么awk的格式工作原理:记录和域内建变量的用法1.FS2.OFS3.RS4.ORS5.NF6.NRBEGIN和END语句块常见案例1.使用NR行号提取ip2.打印UID小于10的账号名称和UID信息3.数学运算4.AWK打印硬盘设备名称,默认以空... 查看详情