awk详细使用方法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_43058911/article/details/102373998

awk介绍

报告生成器,格式化文本输出
多种版本:New awk(nawk)、GNU awk(gawk)
Linux中使用的是gawk:模式扫描和处理语言,awk其实是软链接指向了gawk。
	[root@centos7 ~]#which awk
	/usr/bin/awk
	[root@centos7 ~]#ll /usr/bin/awk
	lrwxrwxrwx. 1 root root 4 Aug 25 12:51 /usr/bin/awk -> gawk

awk工作原理:

1、如果有DEGIN{action;..}语句,则执行语句块中的语句
2、从文件或标准输入读取一行,然后执行pattern{action;..}语句块,awk也是逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
3、当读至输入流末尾时,如果有END{action}语句,则执行语句块中的内容
	BEGIN语句块在awk开始从输入流中读取行之前被执行,是一个可选的语句块,比如变量初始化,打印输出表格的表头等语句通常可以写在BEGIN语句块中。
	END语句块在awk从输入流中读取完所有的行之后被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,也是一个可选语句块。
		例如:awk 'BEGIN{print 1+2}{print $0}END{print "hello world"}' /etc/fstab	:打印内容外,第一行为3,尾部位hello world。
	pattern语句块中的通用命令是最重要的部分,也是可选的,如果没有pattern语句块,则默认执行{print},就是打印每一个读取到的行,awk读取的每一行都会执行该语句块

基本格式:awk [ooption] ‘program’ file…

选项:
	-F:指定输入分隔符,例 -F:
	-v var=vale:变量赋值,例:-v FS=:,也可使用自定义变量:-v name=vlaue		

print的格式:print $1,$2..
	要点:
		逗号为分隔符,要不输出是连在一起的,加逗号,输出是有一个空格分割开两段内容。
		如果print后不跟任何参数,默认为print $0。
		print后可以跟任何数,字符,数字,变量或awk的表达式,如果要当作字符串处理加引号,如果当作变量和运算不用加引号。
			例:'{print num}'	:num当作变量
				'{print "num"}'	:num当作普通字符串
	
	program就是表示'{###}'内的内容。通常是被放在单引号中
		program又分为:pattern{action statements;..}		pattern:模式  statement:声明
			pattern和action
				pattern部分决定动作语句何时出发及触发事件
				action statements对数据进行处理,放在{}内指明

分隔符、域和记录

	awk执行时,由分隔符分隔的字段标记$1,$2...$n称为字段标识,$0为所有字段,所谓字段就是将一行内容使用分隔符分出来的字段。
	在awk专业术语中,每一行称为记录
	如果省略action位的动作命令,默认执行print $0的操作

awk的默认分隔符为空格,不论是tab的空格,还是多个空格,都视为一个空格。

示例:
	awk '{print $0}' /etc/passwd 	:打印输出passwd文件的每一行
	awk '{print "abc"}' /etc/passwd	:打印输出abc,但是指向的文件时passwd文件,所以打印abc的次数就是passwd文件的行数
		'{print "abc"}'中:abc如果要当作字符串输出就必须加引号,不加引号会被当作变量使用,而系统中没有abc变量,输出会变为空
	awk '{print 1+2}' /etc/fstab	:算数运算,输出结果是3,指向fstab文件,所以就输出3的次数就是fstab文件的行数
		'{print "1+2"}'	:如果加了引号,会被认为是字符串,不再认为是算数运算。输出结果就是1+2。
	awk 'BEGIN{print 1+2}'	:输出为3,BEGIN的作用就是开始读取数据流前输出一次,后面没有跟文件,所以只输出了一次。
	awk 'BEGIN{print 1+2}{print $0}' /etc/fstab :输出为fstab文件内容和根据BEGIN的作用输出第一行为3。
	awk 'BEGIN{print 1+2}{print $0}END{print "hello world"}' /etc/fstab	:打印内容外,第一行为3,尾部位hello world。
	
	awk -F: '{print $1"\t"$3}' /etc/passwd	:输出tab键为分隔

awk变量

内置和自定义变量,自定义需要使用 -v 选项。

	FS:输入字段分隔符,意思是用什么符号对文件的每行内容进行分割,默认为空白字符。
		例:awk -v FS=":" '{print $1,$3}' /etc/passwd	:使用冒号对passwd文件进行分割,然后取第一段和第三段。
			awk -F: '{print $1,$3}' /etc/passwd		:意思和上面一样
				两者的区别在于,-F是选项,FS是变量,既然是变量就可以引用
				比如:awk -v FS=":" '{print $1FS$3}' /etc/passwd	:print输出是引用FS变量值:,输出就位root:0,而-F选项不能引用
			awk也可以引用shell中的变量
				比如:shell中定义变量:fs=:
					awk引用:awk -v FS=$fs '{print $1FS$3}' /etc/passwd
	
	OFS:输出字段分隔符,意思是输出的时候使用什么符号对匹配到的内容分隔开,默认为空白字符
		例:awk -v FS=":" -v OFS="%" '{print $1,$3}' /etc/passwd
			匹配的时候使用FS定义的:冒号作为分隔符匹配,输出的时候用OFS定义的%作为分隔输出。结果例如:root%0
	
	RS:输入记录(字段)分隔符,指定输入时的换行符,awk默认的换行符认为是回车换行(\n),使用RS变量定义后,使用RS自定义的换行符。
		例:file1文件内容
			1:2:3
			4:5:6
			7:8:9
		命令:awk -v RS=":" '{print $1}' file1 
		输出:	1
				2
				3
				5
				6
				8
				9
		解释:RS指定:冒号作为换行符,原有的回车换行(\n)不再认为是换行符,所以每个:冒号分隔开的数字被认为是单独的一行,又叫记录
			  为什么没有4和7呢,因为原有的回车换行(\n),不再是换行符了,所以3和4被认为是一行,只是他们之间有一个\n而已,这里又只打印了$1,4被认为是$2.
	
	ORS:输出记录(字段)分隔符,输出时用指定符号代替换行符,将原有换行符替换为ORS指定的换行符。
		例:file1文件内容
			1:2:3
			4:5:6
			7:8:9
		命令:awk -v ORS="%" '{print $1}' file1
		输出:1:2:3%4:5:6%7:8:9%
		解释:将原有的回车换行(\n),替换为%

	NF:字段的数量,指定分隔符时,根据指定的分隔符判断出一行内有几个字段(记录).
		例:  passwd文件内容
			  root:x:0:0:root:/root:/bin/bash
		命令:awk -F: '{print NF}' passwd
		输出:7
		解释:以冒号为分隔符分开的7个字段,所以输出7
		
		命令:awk -F: '{print $NF}' passwd
		输出:/bin/bash
		解释:因为NF的值为7,第一个例子可看出,$NF就等于$7,所以就输出第7个字段
		
		命令:awk -F: '{print $(NF-1)}' passwd
		输出:/root
		解释:算术运算$(NF-1)=$($7-1),所以输出第6个字段
	
	NR:字段(记录)的编号,指定记录分隔符后,NR对其进行编号
		例:file1文件内容
			a:b:c
			d:e:f
			g:h:i
		命令:awk -v RS=":" '{print NR$0}' file1
		输出:1a
			  2b
			  3c
			  d
			  4e
			  5f
			  g
			  6h
			  7i
		解释:RS指定了(字段)记录分隔符,每个冒号都被作为换行符,print $0是打印每行内容,NR是为每行编号,c和d之间没有冒号,被认为是一行。
		
		命令:awk -F: '{print NR,$1}' /etc/passwd /etc/shadow
		输出:1 root
			  2 bin
			  3 daemon
			  ...
			  45 ning
			  46 root
			  ...
			  90 ning
		解释:-F:指定分隔符,print $1取两个文件第一列,NR为其编号,所以两个文件合并总共多少条目。
		如果使两个文件分别编号,使用下面这个变量、
		
		awk 'NR%2==0{print NR,$0}' /etc/passwd	:取偶数行
		awk 'NR%2==1{print NR,$0}' /etc/passwd	:取奇数行
	
	FNR:各文件分别编号,记录号
		例/etc/passwd、/etc/shadow文件
		命令:awk -F: '{print FNR,$1}' /etc/passwd /etc/shadow
		输出:1 root
			  2 bin
			  ...
			  45 ning
			  1 root
			  ...
			  45ning
		输出的编号将会分开显示,两个文件的第一行都是root,最后一行都是ning
		
	FILENAME:打印输出时添加上文件名
		例:/etc/passwd
		命令:awk '{print FNR,FILENAME,$1}' /etc/passwd /etc/shadow
		输出:1 /etc/passwd root
			  2 /etc/passwd bin
			  ...
			  45 /etc/passwd ning
			  1 /etc/shadow root
			  2 /etc/shadow bin
			  ...
			  45 /etc/shadow ning
			  
	ARGC:命令行参数的个数
		例:awk -F: '{print ARGC}' /etc/fstab /etc/passwd
		   awk 'BEGIN{print ARGC}' /etc/passwd /etc/fstab
		输出:3
		解释:此命令的参数3个,下面介绍为什么是3个参数。
		
	ARGV:数组,保存的是命令所给定的各参数
		例:awk 'BEGIN{print ARGV[0]}' /etc/passwd /etc/fstab 
		输出是:ARGV[0]输出是awk。
		解释:awk中认为一条命令中的awk为第一个参数,表达式和选项不能作为参数,ARGV[0]表示为第一个参数,ARGV[1]输出/etc/passwd,ARGV[2]输出是/etc/fstab
		
	自定义变量(区分字符大小写)
		-v var=value
		在program中直接定义,在{print $1}括号内,例:{name="cheng";print $1}
			例如:awk -F: '{name="cheng";print name,$1}' /etc/passwd
			输出:cheng root
				  cheng bin
				  cheng daemon
				  ...

printf命令

	格式:print "format",item1,item2..	(item:项)
		必须制定format格式
		不会自动换行,需要换行,给出换行控制符号"\n"
		format中需要分别为后面每个item制定格式符
	
	格式符:与item一一对应
		%s:显示字符串
		%d,%i:显示十进制数
		%e,%E:显示科学计数法整数
		%f:显示浮点数
		%g,%G:以科学计数法或浮点形式显示数值
		%u:无符号整数
		%%:显示%本身
		%c:显示字符的ASCII码
	
	修饰符
		#[.#]:第一个数字控制显示的宽度,第二个数字表示小数点精度,例:%3.1f,带.点和后面的数字宽度为3,小数位只留1位
		-	:左对齐,默认为右对齐,例:%-15s:15个字符的宽度
		+	:显示字符的正负符号
		
	例:awk -F: '{printf "%-20s  %-5d\n",$1,$3}' /etc/passwd
	输出:	root                  0    
			bin                   1    
			daemon                2    
			adm                   3    
			lp                    4    
			sync                  5    
			shutdown              6    
			halt                  7    
			mail                  8    
			operator              11   
			games                 12   
			ftp                   14   
			nobody                99   
			systemd-network       192  
			dbus                  81   
	解释:%-20s:左对齐预留20位字符,%-5d:左对齐预留5位数字。不写-的话就是默认的右对齐

算数操作符:

	x+y,x-y,x*y,x/y,x^y,x%y
	-x:转换为负数
	+x:将字符串转换为数值

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

赋值操作符:

	=,+=,*=,/=,^=,%=,++,--
	例:awk 'BEGIN{i=1;print ++i,i}'	输出:2 2	:先加
		awk 'BEGIN{i=1;print i++,i}'	输出:1 2	:后加
单=号用于赋值,双等号==用于判断是否相等。

逻辑操作符:与&&,或||,非!

	示例:
		awk -F: '$3>=0 && $3<=1000 {print $1,$3}' /etc/passwd
			passwd文件中3个字段中是用户的UID,当UID>0并且<=1000时,就打印用户和UID,否则忽略
		awk -F:	'$3==0 || $3 >=1000 {print $1,$3}' /etc/passwd
			uid==0或者>=1000时,就打印用户和uid,否则忽略
		awk -F: '!($3==0){print $1,$3}' /etc/passwd
			取反,UID不等于0时就打印用户和UID
		awk -F: '!($3>=500){print $1,$3}' /etc/passwd
			取反,UID不大于500时,就打印用户和UID,否则忽略

		awk -F: '$3>0 && $3<500{print $1,$3}' /etc/passwd

条件表达式(三目表达式)

	{select?if-true-exp:if-false-exp}	:如果真就怎样。如果假就怎样
	
	例:awk '{$3>=1000?type="common":type="system";{print type,$1,$3}}' /etc/passwd
	输出:system avahi 70
		  system postfix 89
		  system tcpdump 72
		  common cheng 1000
		  common ning 1001
	解释:如果UID大于等于1000,type变量值就位common,否则type变量值就为systemc,然后打印。输出UID小于1000前面加systemc。大于1000前面加common。

基于正则表达式模式匹配,定界

	根据模式条件,过滤匹配到的行,再做处理
	
	-F选项和program都可以使用正则表达式,两者还可以同时存在使用正则表达式
	
	如果未指定:空模式,匹配每一行
	
	/pattern模式/:仅处理能够被模式匹配到的行,需要用/ /括起来
		例:  df | awk -F "[[:space:]]+|%" '/^\/dev\/sd/{print $1,$5}'
		输出:/dev/sda5 4
			  /dev/sda2 1
			  /dev/sda1 16

		例:获取特定状态的IP地址	
			ss -nt|awk -F"[[:space:]]+|:" '/^ESTAB/{print $6}'
			ss -nt|awk -F"[[:space:]]+|:" '/^ESTAB/{print $(NF-2)}'
			ss -nt|awk -F"[[:space:]]+|:" '/ESTAB/{print $(NF-2)}'|sort|uniq -c | awk '{print $1}'
				ESTAB状态下IP出现的次数

关系表达式,结果为真才处理

		真:结果为非0值,非空
			awk '1{print $0}' /etc/fstab
			awk '!0{print $0}' /etc/fstab
		假:结果为空值或0
			awk '0{print $0}' /etc/fstab
			awk '!1{print $0}' /etc/fstab
		取反:!	
			例:awk -F: '!($3%2==0){print $1,$3}' /etc/passwd     
			输出:bin 1
				 adm 3
				 sync 5
				 halt 7
				 operator 11
				 nobody 99
			   	 dbus 81
			 	 polkitd 999
				 postfix 89
				 nginx 1001
				 dhcpd 177
				 tss 59
			说明:($3%2==0)取模为0为UID偶数的,! 取反取UID为奇数的用户
		
		例:awk -F: '$3>=1000{print $1,$3}' /etc/passwd
		输出:nfsnobody 65534
			 cheng 1000
			 ning 1001
		说明:$3在大于等于1000才执行后面的操作。
		
		示例:	
			awk '!0' /etc/passwd
			awk '!1' /etc/passwd
			awk -F: '$3>=1000{print $1,$3}' /etc/passwd
			awk -F: '$3<1000{print $1,$3}' /etc/passwd
			awk -F: '$NF=="/bin/bash"{print $1,$3,$7}' /etc/passwd
				$NF的值是不是/bin/bash,是就打印,不是不打印,过滤用户shell不是/bin/bash。
			lastb | awk '$3 ~ /^[0-9]+/{print $3}'
				说明:$3字段是不是以数字开头的,是就打印,不是数字的不打印

行范围

		awk不支持直接给出数字用于定界,使用正则表达式/pat1/,/pat2/
		例:
			awk '/^ftp/,/^rpc/' /etc/passwd
			awk '/^UUID/' /etc/fstab
		变量的使用数字定界:
			awk 'NR >=10 && NR <=20{print NR,$0}' /etc/passwd

awk控制语句

	if(condition){cmd;..}
	if(condition){cmd;..}else if(condition){cmd;..}else{cmd;}
	while(conditon){cmd;..}
	do{cmd;..}while(condition)
	for(exp1;exp2;exp3){cmd;..}
	array[num]
	
	break
	continue
	exit

awk控制语句if else

		语法:if(condition){cmd;..}else {cmd}
			  if(condition){cmd;..}else if(condition){cmd;..}else {cmd}
		使用场景:对awk取得的整行或某个字段做条件判断
		示例:
			awk -F: '{if($3>=1000){print $1,$3}}' /etc/passwd
			awk -F: '{if($NF=="/bin/bash"){print $1,$NF}}' /etc/passwd
			awk -v a=84 'BEGIN{if(a <60){print "no pass"}else if(a <=80){print "soso"}else{print "good"}}'

awk控制语句while循环

		对一行中的不同字段进行处理。
		语法:while(condition){cmd;..}
		条件:"真",进入循环
			  "假",退出循环
		使用场景:对一行内的多个字段逐一类似处理时使用
					对数组中的各元素逐一处理时使用
		示例:
			awk -F: 'NR==1{i=1;while(i<=NF){print length($i),$i;i++}}' /etc/passwd
				对passwd文件第一行NR定义。进行字段循环,打印每个字段的长度length。length是系统中的函数。
			awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){print length($i),$i;i++}}' /boot/grub2/grub.cfg 
				统计grub文件中Linux16那一行每个字段的长度
			awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){if(length($i) >=10)print length($i),$i;i++}}' /boot/grub2/grub.cfg 
				统计grub文件中Linux16那一行每个字段的长度,每个字段长度大于10的才显示
		
		例:
		生成file1文件
			for i in {1..1000};do if [ $i -eq 1 ];then echo -n "$RANDOM" > file1;else echo -n ",$RANDOM" >> file1;fi;done
		计算file1文件中最大数和最小数
			awk -F"," '{i=1;max=$1;min=$1;while(i<=NF){if($i >max){max=$i}else if($i <min){min=$i};i++}}END{print "max="max,"min="min}' file1

awk控制语句do-while循环

		语法:do{cmd;..}while(condition)
		意义:无论真假,先执行一次do{cmd}中的命令,然后在while()判断真假,真就继续执行do{cmd}命令,假就退出。适用于无论真假都先执行一次命令
		例:
			awk 'BEGIN{i=1;do{num+=i;i++;}while(i <=100){print num}}'	:先执行再判断。
			awk 'BEGIN{i=1;while(i <=100){num+=i;i++}{print num}}'		:先判断再执行。

awk控制语句for循环

		语法:for(exp1;exp2;exp3){cmd;...}
			例:
				awk 'BEGIN{for(i=1;i<=100;i++){num+=i}{print num}}'
				awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){print length($i),$i}}' /etc/grub2.cfg

		特殊用法:能够遍历数组中的元素,后面会说。
			语法:for(var in array){for-body}

continue语句

		例:awk 'BEGIN{for(i=1;i<=100;i++){if(i==50)continue;num+=i}{print num}}'	:等于50跳过本次循环
		输出:5000

break语句

		例:awk 'BEGIN{for(i=1;i<=100;i++){if(i==50)break;num+=i}{print num}}'
		输出:1225

next语句:跳过当前行,进行下一行处理

		例:awk '{if(NR%2==0)next;print NR,$0}' /etc/passwd	:NR行号,取模为0时跳过当前行。
			awk '{if(NR%2==1)next;print NR,$0}' /etc/passwd	:NR行号,取模为1是跳过当前行。
			awk 'NR%2==0{print NR,$0}' /etc/passwd
			awk 'NR%2==1{print NR,$0}' /etc/passwd

awk数组

	在shell中数组又分为普通数组和关联数组,在awk中使用的只有关联数组。
	关联数组:array[index-exp]
	index-exp:
		可使用任意字符串;字符串要用双引号引起来
		如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”
		若要判断数组中是否存在某元素,要是用"index in array"格式进行遍历
	例:定义数组:
		awk 'BEGIN{week["mon"]="monday";week["tue"]="tuesday";week["sun"]="sunday";print week["mon"]}'
	例:file1文件内容,将文件内容去重,只是锻炼awk思维!
		abc
		abc
		ddd
		ccc
		ccc
		eee
		eee
	命令:awk '!line[$0]++{print $0}' file1
	输出:abc
		  ddd
		  ccc
		  eee
	解释:将表达式拆分开看,! line[$0] ++,$0为一行,取第一行line[$0]=line[abc]为空值为假,然后!取反为真,为真后++得出第一次line[abc]=1,print输出第一行
		  第二行还是abc,line[$0]=line[abc],因为之前++后得出line[abc]=1,所以这次!取反后为假,为假后print不输出。接着++后line[abc]=2
		  往后延伸只要有abc就一直++,值一直为真,一直取反,一直为假,然后不输出,这样只输出了第一个line[abc]。所以就是去重,后面的内容一样步骤。
	awk '{!line[$0]++;print $0,line[$0]}' f2	:查看上面描述的数组值

数组的遍历,使用for(var in array)

		格式:for(var in array){print ...}
		var遍历array的每个索引从而实现遍历输出。
		例:awk 'BEGIN{week["mon"]="monday";week["tue"]="tuesday";week["sun"]="sunday";for(i in week)print week[i]}'
			解释:i的值来自数组的索引,每次print week[i]时,其实就是print week["mon"]/print week["tue"]。这样循环实现遍历数组,输出数组值
		注意:awk的数组打印输出时时无序的

	例:
		netstat -ant| awk '/^tcp/{state[$6]++}END{for(i in state){print i,state[i]}}'
			统计状态次数
		ss -nt|awk -F"[[:space:]]+|:" 'NR>1{ip[$6]++}END{for(i in ip){print i,ip[i]}}'
			统计已连接IP的次数
		awk '/^UUID/{fs[$3]++}END{for(i in fs){print i,fs[i]}}' /etc/fstab
			统计fstab文件中文件系统出现的次数

	练习:[root@centos7_1 data]#cat f1 文件内容
			name sex score
			a    m   90
			b    f   80
			c    f   99
			d    m   88
			a    m   90
			e    f   23 
			t    m   56
			d    f   89
	计算得出男女的成绩平均数
	命令:awk 'NR>1{score[$2]+=$3;num[$2]++}END{for(i in score){print i,score[i]/num[i]}}' f1

awk函数

	数值处理
		rand():返回一个初始值。
			例:awk 'BEGIN{print rand()}'
				0.237788
		srand()要生成0和1的随机数配合另一个函数使用
			例:awk 'BEGIN{srand();print rand()}'
				awk 'BEGIN{srand();print rand()*100}'	:生成100之内的带小数的随机数
		int():去掉小数点生成随机数
			例:awk 'BEGIN{srand();print int(rand()*100)}'
	字符串处理
		length():字符串的长度
			例:awk 'BEGIN{print length("aaaaaa")}'
		sub(r,s,[t]):对t位字符串搜索r位表示的模式匹配到的内容,并将第一个匹配到的内容替换为s位表示的内容
			例:echo "2019:09:18 15:10:33" | awk 'sub(/:/,"-",$1)'
			    2019-09:18 15:10:33
				echo "2019:09:18 15:10:33" | awk 'sub(/:/,"-",$2)'
				2019:09:18 15-10:33
		gsub(r,s,[t]):对t位字符串进行搜索r位表示的模式匹配的内容,并全部替换为s位表示的内容
			例:echo "2019:09:18 15:10:33" | awk 'gsub(/:/,"-",$1)'
				2019-09-18 15:10:33
				echo "2019:09:18 15:10:33" | awk 'gsub(/:/,"-",$0)'
				2019-09-18 15-10-33
		split(s,array,[r]):以r位为分隔符,切割字符串s位,并将切割后的结果保存至array表示的数组中,第一个索引值为1、第二个索引值为2...
			例:echo "2019:09:18 15:10:33" |awk 'split($0,digit,":"){for(i in digit){print i,digit[i]} }'
				4 10
				5 33
				1 2019
				2 09
				3 18 15

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

awk中调用shell命令

	system命令
		空格是awk中的字符串连接符,如果system中需要使用awk中变量可以使用空格分隔,或者说除了awk的变量外其他一律用""引起来
			例:
				awk 'BEGIN{system("ls /")}'		:普通型
				awk 'BEGIN{dir="/";system("ls "dir)}'	:变量型,注意:"ls "中有空格。没有空格就相当于ls/,会报错的
				awk 'BEGIN{system("hostname")}'

判断UID是否大于等于500,如果为真就显示为普通用户,如果为假就显示为系统或管理用户

命令:	awk -F: '{$3 >500?type="common user":type="system user";{print type,$1,$3}}' /etc/passwd
输出:	system user root 0
		system user bin 1
		system user daemon 2
		system user adm 3
		system user lp 4
		system user sync 5
		system user shutdown 6
		system user halt 7
		system user mail 8
		system user operator 11
		system user games 12
		system user ftp 14
		system user nobody 99
		system user systemd-network 192
		system user dbus 81
		common user polkitd 999
		system user sshd 74
		system user postfix 89
		common user cheng 1000
		common user nginx 1001
		system user apache 48
		system user dhcpd 177
		system user tss 59
		common user geoclue 998
说明:当'{$3 >500条件为真时,变量type的值为common user,条件为假时变量type值为system user,判断并打印输出

取UID为奇数的用户

例:awk -F: '!($3%2==0){print $1,$3}' /etc/passwd     
输出:bin 1
	 adm 3
	 sync 5
	 halt 7
	 operator 11
	 nobody 99
	 dbus 81
	 polkitd 999
	 postfix 89
	 nginx 1001
	 dhcpd 177
	 tss 59
说明:($3%2==0)取模为0为UID偶数的,! 取反取UID为奇数的用户

统计web服务访问日志中的ip访问量

命令:awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log
输出:192.168.0.120 10
	 192.168.0.198 12
说明:数组ip的值为$1,而$1就是日志中的IP地址,自身++计算得出同一IP出现的次数,
END语句最后做总结,for循环中 i 的值来自于ip数组变量也就是IP地址,ip[i]是取IP出现的次数

猜你喜欢

转载自blog.csdn.net/qq_43058911/article/details/102373998