Linux AWK命令

本文详细总结了Linux中的AWK命令,包括内置变量、格式化输出printf、模式匹配、表达式用法、条件与循环语句、字符串函数以及数组的使用。还额外提及了Shell中数组的常见操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.awk的内置变量总结:

	内置变量:
		$0				打印行所有信息
		$1~$n				打印行的第1到n个字段的信息
		NF	Number Field		处理行的字段个数
		NR	Number Row		处理行的行号
		FNR	File Number Row		多文件处理时,每个文件单独记录行号
		FS	Field Separator		字段分割符,不指定时默认以空格或tab键分割
		RS	Row Separator		行分隔符,不指定时以回车分割\n
		OFS	 Output Filed Separator	输出字段分隔符。
		ORS	 Output Row Separator	输出行分隔符
		FILENAME			处理文件的文件名
		ARGC				命令行参数个数
		ARGV				命令行参数数组

2.awk格式化输出printf总结:

	格式符
		%s		打印字符串
		%d		打印10进制数
		%f		打印浮点数
		%x		打印16进制数
		%o		打印8进制数
		%e		打印数字的科学计数法格式
		%c		打印单个字符的ASCII码
		
	修饰符
		-		左对齐
		+		右对齐
		#		显示8进制在前面加0,显示16进制在前面加0x
		
		
	格式符示例:
		1、以字符串格式打印/etc/passwd中的第7个字段,以":"作为分隔符
		
			awk 'BEGIN{FS=":"} {printf "%s",$7}' /etc/passwd
		
		2、以10进制格式打印/etc/passwd中的第3个字段,以":"作为分隔符
		
			awk 'BEGIN{FS=":"} {printf "%d\n",$3}' /etc/passwd
		
		3、以浮点数格式打印/etc/passwd中的第3个字段,以":"作为分隔符
		
			awk 'BEGIN{FS=":"} {printf "%0.3f\n",$3}' /etc/passwd
		
		4、以16进制数格式打印/etc/passwd中的第3个字段,以":"作为分隔符
		
			awk 'BEGIN{FS=":"} {printf "%#x\n",$3}' /etc/passwd
		
		5、以8进制数格式打印/etc/passwd中的第3个字段,以":"作为分隔符
		
			awk 'BEGIN{FS=":"} {printf "%#o\n",$3}' /etc/passwd
		
		6、以科学计数法格式打印/etc/passwd中的第3个字段,以":"作为分隔符
		
			awk 'BEGIN{FS=":"} {printf "%e\n",$3}' /etc/passwd
		
	修饰符示例:
		
		1、左对齐格式
		2、右对齐格式
		3、打印8进制或16进制数字是在前面加#

3.awk模式匹配用法总结:

第一种方法:RegExp
第二种方法:运算符匹配

<1>RegExp

	匹配/etc/passwd文件行中含有root字符串的所有行
		awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd
	匹配/etc/passwd文件行中以yarn开头的所有行
		awk 'BEGIN{FS=":"}/^yarn/{print $0}' /etc/passwd

<2>运算符匹配

	关系运算符匹配:
		<			小于
		>			大于
		<=			小于等于
		>=			大于等于
		==			等于
		!=			不等于
		~			匹配正则表达式
		!~			不匹配正则表达式
		
	(1)、以:为分隔符,匹配/etc/passwd文件中第3个字段小于50的所有行信息
		awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd
	(2)、以:为分隔符,匹配/etc/passwd文件中第3个字段大于50的所有行信息
		awk 'BEGIN{FS=":"}$3>50{print $0}' /etc/passwd
	(3)、以:为分隔符,匹配/etc/passwd文件中第7个字段为/bin/bash的所有行信息
		awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd
	(4)、以:为分隔符,匹配/etc/passwd文件中第7个字段不为/bin/bash的所有行信息
		awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' /etc/passwd
	(5)、以:为分隔符,匹配/etc/passwd中第3个字段包含3个以上数字的所有行信息
		awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' /etc/passwd
	
	布尔运算符匹配:
		||			或
		&&			与
		!			非
		
(1)、以:为分隔符,匹配/etc/passwd文件中包含hdfs或yarn的所有行信息
		awk 'BEGIN{FS=":"}$1=="hdfs" || $1=="yarn" {print $0}' /etc/passwd
(2)、以:为分隔符,匹配/etc/passwd文件中第3个字段小于50并且第4个字段大于50的所有行信息
awk 'BEGIN{FS=":"}$3<50 && $4>50 {print $0}' /etc/passwd

4.awk动作中的表达式用法总结:

算数运算符
	+				加
	-				减
	*				乘
	/				除
	%				取模
	^或**			乘方
	++x				在返回x变量之前,x变量加1
	x++				在返回x变量之后,x变量加1
	--x				在返回x变量之前,x变量减1
	x--				在返回x变量之后,x变量减1
	
1、使用awk计算/etc/services中的空白行数量
	awk '/^$/{sum++}END{print sum}' /etc/services
2、计算学生课程分数平均值,学生课程文件内容如下:

	zhang	80	90	96	98
	wang	93	98	92	91
	li	78	76	87	92
	zhao	86	89	68	92
	qian		85	95	75	90
	liu		78	88	98	100
	
	awk 'BEGIN{printf "%-8s%-8s%-8s%-8s%-8s%s\n","Name","Yuwen","Math","English","Pysical","Average"}{total=$2+$3+$4+$5;AVG=total/4;printf "%-8s%-8d%-8d%-8d%-8d%0.2f\n",$1,$2,3,$4,$5,AVG}' student.txt

5.awk动作中的条件及循环语句

	条件语句:
	
		if(条件表达式1)
			动作
		else if(条件表达式2)
			动作
		else
			动作
			
	循环语句:
	
		while循环:
			while(条件表达式)
				动作
				
		do while循环:
			do
				动作
			while(条件表达式)
			
		for循环:
			for(初始化计数器;计数器测试;计数器变更)
				动作
				
	1、以:为分隔符,只打印/etc/passwd中第3个字段的数值在50-100范围内的行信息

		代码:
		BEGIN{
			FS=":"
		}
		
		{
			if($3<50)
			{
				printf "%-20s%-25s%-5d\n","UID<50",$1,$3
			}
			else if($3>50 && $3<100)
			{
				printf "%-20s%-25s%-5d\n","50<UID<100",$1,$3
			}
			else
			{
				printf "%-20s%-25s%-5d\n","UID>100",$1,$3
			}
		}
	2、计算下列每个同学的平均分数,并且只打印平均分数大于90的同学姓名和分数信息
			
		Name	Chinese		English		Math		Physical	Average
		zhang	80			90			96			98
		wang	93			98			92			91
		li	78			76			87			92
		zhao	86			89			68			92
		qian	85		        95			75			90
		liu	78			88		        98		        100	
				

	stud.awk文件:
            BEGIN{
		printf 			"%-10s%-10s%-10s%-10s%-10s%-10s\n","Name","Chinese","English","Mat			h","Physical","Average"
	}

	{
		total=$2+$3+$4+$5
		avg=total/4
		if(avg>90)
		{
			printf "%-10s%-10d%-10d%-10d%-10d%-0.2f\n",						$1,$2,$3,$4,$5,avg
			score_chinese+=$2
    			score_english+=$3
    			score_math+=$4
    			score_physical+=$5
		}

	}

	END{

		printf 				"%-10s%-10d%-10d%-10d%-10d\n","",score_chinese,score_engli				sh,score_math,score_physical

	}

	3、计算1+2+3+4+...+100的和,请使用while、do while、for三种循环方式实现

6.awk中的字符串函数

length(str)						计算长度
index(str1,str2)				返回在str1中查询到的str2的位置
tolower(str)					小写转换
toupper(str)					大写转换	
split(str,arr,fs)				按fs分隔字符串,并保存到数组中
match(str,RE)					返回正则表达式匹配到的子串的位置
substr(str,m,n)					截取子串,从m个字符开始,截取n位。n若不指定,则默认截取到字符串尾
sub(RE,RepStr,str)				替换查找到的第一个子串
gsub(RE,RepStr,str)				替换查找到的所有子串

1、以:为分隔符,返回/etc/passwd中每行中每个字段的长度	

	root:x:0:0:root:/root:/bin/bash
	4:1:1:1:4:5:9
	代码:
	BEGIN{
		FS=":"
	}
	
	{
		i=1
		while(i<=NF)
		{
			if(i==NF)
				printf "%d",length($i)
			else
				printf "%d:",length($i)
			i++
		}
		print ""
	}

2、搜索字符串"I have a dream"中出现"ea"子串的位置	

	(1)、awk 'BEGIN{str="I hava a dream";location=index(str,"ea");print location}'
	(2)、awk 'BEGIN{str="I hava a dream";location=match(str,"ea");print location}'
	
3、将字符串"Hadoop is a bigdata Framawork"全部转换为小写

	awk 'BEGIN{str="Hadoop is a bigdata Framework";print tolower(str)}'
	
4、将字符串"Hadoop is a bigdata Framawork"全部转换为大写
	
	awk 'BEGIN{str="Hadoop is a bigdata Framework";print toupper(str)}'
	
5、将字符串"Hadoop Kafka Spark Storm HDFS YARN Zookeeper",按照空格为分隔符,分隔每部分保存到数组array中

	awk 'BEGIN{str="Hadoop Kafka Spark Storm HDFS YARN Zookeeper";split(str,arr);for(a in arr) print arr[a]}'

6、搜索字符串"Tranction 2345 Start:Select * from master"第一个数字出现的位置

	awk 'BEGIN{str="Tranction 2345 Start:Select * from master";location=match(str,/[0-9]/);print location}'

7、截取字符串"transaction start"的子串,截取条件从第4个字符开始,截取5位

	awk 'BEGIN{str="transaction start";print substr(str,4,5)}'
	awk 'BEGIN{str="transaction start";print substr(str,4)}'
	
8、替换字符串"Tranction 243 Start,Event ID:9002"中第一个匹配到的数字串为$符号

	awk 'BEGIN{str="Tranction 243 Start,Event ID:9002";count=sub(/[0-9]+/,"$",str);print count,str}'
	awk 'BEGIN{str="Tranction 243 Start,Event ID:9002";count=gsub(/[0-9]+/,"$",str);print count,str}'

7.awk中数组的用法:

在awk中,使用数组时,不仅可以使用1.2..n作为数组下标,也可以使用字符串作为数组下标

当使用1.2.3..n时,直接使用array[2]访问元素;需要遍历数组时,使用以下形式:

	str="Allen Jerry Mike Tracy Jordan Kobe Garnet"
	split(str,array)
	for(i=1;i<=length(array);i++)
		print array[i]


当使用字符串作为数组下标时,需要使用array[str]形式访问元素;遍历数组时,使用以下形式:
	array["var1"]="Jin"
	array["var2"]="Hao"
	array["var3"]="Fang"
	
	for(a in array)
		print array[a]
		
典型常用例子:
	1、统计主机上所有的TCP连接状态数,按照每个TCP状态分类
	
		netstat -an | grep tcp | awk '{array[$6]++}END{for(a in array) print a,array[a]}'
		
	2、计算横向数据总和,计算纵向数据总和
	
		allen	80	90	87	91	348
		mike	78	86	93	96	256
		Kobe	66	92	82	78	232
		Jerry	98	74	66	54  356
		Wang	87	21	100	43  322
				234 342 451 456 342
		
		BEGIN {
			printf "%-10s%-10s%-10s%-10s%-10s%-10s\n","Name","Yuwen","Math","English","Physical","Total"
		}
		
		{
			total=$2+$3+$4+$5
			yuwen_sum+=$2
			math_sum+=$3
			eng_sum+=$4
			phy_sum+=$5
			printf "%-10s%-10d%-10d%-10d%-10d%-10d\n",$1,$2,$3,$4,$5,total
		}
		END {
		
			printf "%-10s%-10d%-10d%-10d%-10d\n","",yuwen_sum,math_sum,eng_sum,phy_sum

附:Shell中数组的常见用法:

array=("Allen" "Mike" "Messi" "Jerry" "Hanmeimei" "Wang")

打印元素:			echo ${array[2]}
打印元素个数:		echo ${#array[@]}
打印元素长度:		echo ${#array[3]}
给元素赋值:		array[3]="Li"
删除元素:			unset array[2];unset array
分片访问:			echo ${array[@]:1:3}
元素内容替换:		${array[@]/e/E}	只替换第一个e;${array[@]//e/E}	替换所有的e
数组的遍历:
	for a in ${array[@]}
	do
		echo $a
	done
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值