awk命令

awk

linux三剑客之一,对复杂的文本进行处理,不直接编辑源文件,需要重定向才能保存

内置变量

	ARGC               命令行参数个数
	ARGV               数组,保存的是命令行所给定的个参数
	ENVIRON            支持队列中系统环境变量的使用
	FILENAME           awk浏览的文件名
	FNR                各文件分别计数的行号
	FS                 设置输入域分隔符,等价于命令行 -F选项,默认分割符为空格或tab键
	NF                 浏览记录的域的个数
	NR                 已读的记录数
	OFS                输出域分隔符
	ORS                输出记录分隔符
	RS                 控制记录分隔符
	$0                 变量是指整条记录,$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。
	$NF                是number finally,表示最后一列的信息,跟变量NF是有区别的,变量NF统计的是每行列的总数
	BEGIN              在awk读取输入之前执行的代码块
	END                结尾代码块,对所有行进行处理后再执行的代码块,用于输出结尾信息

常用符号和通配符

数学运算:+,-,*,/, %,++,- -
逻辑关系符:&&, ||, !
比较操作符:>,<,>=,!=,<=,== ~ !~
文本数据表达式:== (精确匹配)
~	波浪号表示匹配后面的模式		
^	 行首定位符	 /^my/  匹配所有以my开头的行
$	 行尾定位符	 /my$/  匹配所有以my结尾的行
.	 匹配除换行符以外的单个字符	 /m..y/  匹配包含字母m,后跟两个任意字符,再跟字母y的行
*	 匹配零个或多个前导字符	 /my*/  匹配包含字母m,后跟零个或多个y字母的行
[]	 匹配指定字符组内的任一字符	 /[Mm]y/  匹配包含My或my的行
[^]	 匹配不在指定字符组内的任一字符	 /[^Mm]y/  匹配包含y,但y之前的那个字符不是M或m的行
&	 保存查找串以便在替换串中引用	 s/my/**&**/  符号&代表查找串。my将被替换为**my**
\<	 词首定位符	 /\<my/  匹配包含以my开头的单词的行
\>	 词尾定位符	 /my\>/  匹配包含以my结尾的单词的行
x\{m\}	 连续m个x	 /9\{5\}/ 匹配包含连续5个9的行
\{m,\}	 至少m个x	 /9\{5,\}/  匹配包含至少连续5个9的行
x\{m,n\}	 至少m个,但不超过n个x	 /9\{5,7\}/  匹配包含连续5到7个9的行

参数的使用实例

awk '{print}'  /etc/passwd     #输出所有域 
	awk '{print $0}'  /etc/passwd  #同上
awk '/root/'  /etc/passwd          #输出含关键字的所有行
awk '{2=="**";print $0}' test.txt  #默认分割符,将第二域的值替换为**,整体输出

-f  指定脚本
	awk -f script.awk  test.txt
	
-F 指定分割符
	awk -F: '{print $1; print $2}'   /etc/passwd   #将每一行的前二个字段,分行输出
	awk -F":" '{print $1,$3}'  /etc/passwd     #多了一个逗号,$1与$3使用空格分隔
	awk -F: '/root/  {print $7}'  /etc/passwd    #输出含关键字的行的对应域
	awk -F: 'NR==5{print}'  /etc/passwd    #显示第5行
	awk -F":" '!/yozo/ {print $2,$4}'  /etc/passwd  #去除匹配行
	
	awk 'NR!=1{print}'  /etc/passwd        #不显示第一行
	awk -F: '{print $1,$3,$4}' OFS="\t"  /etc/passwd  #输出字段1,3,6,以制表符作为分隔符
	awk -F':'  '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:" $0}'  /etc/passwd
		#统计/etc/passwd文件名,每行行号,每行列数,对应的完整行内容
	awk -F: '{printf ("filename:%10s,linenumber:%3s,column:%3s,content:%3f\n",FILENAME,NR,NF,$0)}'  /etc/passwd
		#使用printf代替print
	awk -F: 'NR==2{print "filename:" FILENAME,$0}'   /etc/passwd    #打印第二行信息
	awk -F":" '{print $NF-1}'  /etc/passwd                    #指定分隔符,查找倒数第二列

	awk -F "[/]" 'NR == 4 {print $0,"\n",$1}' /etc/passwd     #这里以/为分隔符,多个分隔符利用[]然后在里面写分隔符即可
		awk -F '[/:]'  '{print $2}'   /etc/passwd   #先使用/进行分隔,在使用:分隔,取指定域
		
cat /etc/passwd | awk -F: 'BEGIN{print "name, shell"} {print $1,$NF} END{print "hello  world"}'
	#添加BEGIN和END
awk '$2 ~ /root/ {print $2,$3}' /etc/passwd    #输出第二列包含"th",输出指定域
awk 'BEGIN{IGNORECASE=1} /mysql/' /etc/passwd  #忽略大小写
awk '$2 !~ /th/ {print $2,$4}' /etc/passwd     #模式取反


-v 定义变量 
	awk -v action="success" 'BEGIN{print action}'   #自定义变量
	awk -v lang=$LANG 'BEGIN {print lang}'          #引用全局变量

IF语句

	必须用在{}中,且比较内容用()扩起来
	awk -F: '{if($1~/mail/) print $1}' /etc/passwd        #简写
	awk -F: '{if($1~/mail/) {print $1}}'  /etc/passwd     #全写
	awk -F: '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd          #if...else...
	awk -F":" '{if(NR>20 && NR<25) print $1}'   /etc/passwd   #获取第20-25行的第一列信息

awk字符串函数

	length()
	index()
	gensub()
	gsub()
	sub()
	substr()
	match()
	split()
	tolower()
	toupper()

	length([string])   #字符串长度
		awk '{print length()}'  test.txt   #返回每一行的字符数
		
	index(in,find)    #在字符串in中查找find的第一个匹配项,返回其位置下标,没有匹配项返回0
		awk 'BEGIN {print index("hello","lo")}'
		
	gensub(regexp,replacement,how[,target]) #将匹配的值进行替换,how取值为g或G的字符串,默认不指定target值则表示$0
		gawk '
			BEGIN {
			a="abcd bef"
			b=gensub("b","B",1,a)  #将b替换为B,1表示默认分隔符的第一域,a为操作对象
			print b}'
		gawk 'BEGIN {a="abcd bef";b=gensub("b","B",1,a);print b}'
		
		gawk '
			BEGIN {
			a="abcd bef"
			b=gensub(/(.+) (.+)/,"\\2 \\1","g",a)
			print b }'
		gawk 'BEGIN {a="abcd bed"; b=gensub(/(.+) (.+)/,"\\2 \\1","g",a); print b}'
		
	gsub(regexp,replacement[,target])  #gsub中的g表示global,全局
		echo "hello,good,hello,good" | awk {' gsub(/hello/, "Hi"); print '}  #将所有匹配的字符串进行替换

	sub(regexp,replacement [,target])  #从左边开始匹配,替换第一个匹配值
		awk 'BEGIN {str="why why study";sub(/why/,"no",str);print str}'  #target为变量,不指定默认取$0

	substr(string,start [,length])  #返回string中指定位置和长度的子字符串,长度大于结尾长度取到结尾
		awk 'BEGIN {s=substr("helloworld",3,4);print s}'

	match(string,regexp [,array])  #匹配子字符串
		echo "heellowoorld" | gawk '{match($0,/(he+).+(wo+)/,arr) ; print arr[1] arr[2] }'
		
	split(string,array [,fieldsep [,seps]])  #将字符串string由fieldsep分隔符分隔,字符串片段存储在array,分隔符存储在seps
		awk 'BEGIN {split("he-ll-o",a,"-",seps); print a[1],a[2],a[3],seps[1],seps[2]}'
		awk 'BEGIN {n=split("he-ll-o",a,"-",seps); print n}'  #返回值为数组的元素个数

	tolower(string)  #将字符串中的所有大写字母转为小写
		awk 'BEGIN {s=tolower("HellO WoRld");print s}'

	toupper(string)  #将字符串中的所有小写字母转为大写
		awk 'BEGIN {s=toupper("HellO WoRld");print s}'
	
	综合:
		#FS读取时列分割符,OFS输出时列分割符,第一域上匹配root字符串用toor替换,输出所有匹配的域
		awk 'BEGIN {FS=":";OFS=":"} gsub(/root/,"toor",$1) {print $0}' test.txt
		#替换所有域匹配的字符串,全部输出
		awk 'BEGIN {FS=":";OFS=":"} gsub(/root/,"ssss") {print $0}'  test.txt
			awk 'BEGIN {FS=":";OFS=":"} gsub(/root/,"ssss",$0) {print $0}'  test.txt

		#区分大小写,输出"fafae"匹配字符d的位置
		awk 'BEGIN {print match("fdfae",/d/)}' 
		#IGNORECASE变量值为1使得匹配区分大小写
		awk 'BEGIN {IGNORECASE=1;print match("sGgGfff",/g/)}' 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值