linux之awk详解

前言

awk不仅仅是Linux系统中的一个命令,而且其还是一种编程语言,可以用来处理数据和生成报告(Excel)。处理的数据可以是一个或多个文件,它是Linux系统最强大的文本处理工具,没有之一。

【语法格式】

awk [option] ‘pattern{action}’ file …
awk [参数] ‘条件{动作}’ 文件 …

awk命令的常用功能

在这里插入图片描述
awk命令的参数选项及说明
在这里插入图片描述

案例1 :显示文件中的第5行

测试文件及内容如下:

#查看测试文件并每行编号
bash-5.0# cat -n reload.sh 
     1  echo "loading..."
     2  # pid=`pidof skeleton.Master`
     3  # kill -HUP $pid
     4  pid=`ps -ef |grep skeleton.Worker| grep -v grep| awk '{print $1}'`
     5  # | xargs kill -USR1
     6  echo $pid
     7  kill -9 $pid
     8  # kill -USR1 $pid
     9  echo "loading success"
bash-5.0# awk "NR==5" reload.sh 
# | xargs kill -USR1 		 #<==和上面内容对比确实是第5行

说明:

首先NR在awk中表示行号(记录号),NR==5表示行号等于5的行。这里需要注意的是必须使用两个等号,在awk中两个等号表示“等于”,一个等号表示赋值,即向一个变量里面放置内容。注意:awk后面所接的内容要用单引号。
命令拓展:显示一部分行的内容,例如显示2-5行。

bash-5.0# awk "NR==2,NR==5" reload.sh
# pid=`pidof skeleton.Master`
# kill -HUP $pid
pid=`ps -ef |grep skeleton.Worker| grep -v grep| awk '{print $1}'`
# | xargs kill -USR1

案例2:给文件每行的内容之前加上行号。

bash-5.0# awk '{print NR,$0}' reload.sh 
	1 echo "loading..."
	2 # pid=`pidof skeleton.Master`
	3 # kill -HUP $pid
	4 pid=`ps -ef |grep skeleton.Worker| grep -v grep| awk '{print $1}'`
	5 # | xargs kill -USR1
	6 echo $pid
	7 kill -9 $pid
	8 # kill -USR1 $pid
	9 echo "loading success"

说明:

这里的NR还是表示行号,$0表示一整行的内容(一行的内容)。print关键字表示显示的内容,相当于是awk内部的一个命令。那么print命令为何要放在花括号中呢?因为这个命令(动作)是“很害羞”的,需要“城墙”保护(花括号)。

案例3:显示文件的第2行到6行,并打印行号。

bash-5.0# awk 'NR==2,NR==5 {print NR,$0}' reload.sh 		#<==注意位置和写法。
	2 # pid=`pidof skeleton.Master`
	3 # kill -HUP $pid
	4 pid=`ps -ef |grep skeleton.Worker| grep -v grep| awk '{print $1}'`
	5 # | xargs kill -USR1

案例4:获取此文件的第1列和第三列、最后一列

bash-5.0# cat 1.txt 
qq:ww:ee:rr:ss:22:3333:221
zz:xxx:sss:ddd:aaa:f
w:e:r:q:f:g:ghh:h:f:f:f:f
qq:ww:ee:rr:ss:22:3333:221
w:e:r:q:f:g:ghh:h:f:f:f:f
qq:ww:ee:rr:ss:22:3333:221
zz:xxx:sss:ddd:aaa:f
qq:ww:ee:rr:ss:22:3333:221
bash-5.0# awk -F ':' '{print $1,$3,$NF}' 1.txt
qq ee 221
zz sss f
w r f
qq ee 221
w r f
qq ee 221
zz sss f
qq ee 221
说明:
  • 这里我们使用了awk的-F参数,注意一定要是大写的,-F参数表示指定分隔符来切割每一行的内容,-F后面可用单双引号或不加引号,但是,建议加双引号。

  • 这里我们指定的分隔符是冒号“:”,这样该行就被不同的冒号切割成了很多个部分。

  • 切成了很多个部分之后,若我们要使用某一个部分该怎么办?使用“$(美元符号)”后面接数字,$1表示第一个部分(第一列),$2(第二列),$3(第三列),依此类推,但$0表示整行。

  • 这里有一个特殊的表示最后一列的方法,就通过$NF来表示最后一列。

案例5:使用awk将文件中的qq替换为tihuan(使用awk函数实现)

bash-5.0# awk '{gsub("qq","tihuan",$0);print $0}' 1.txt
tihuan:ww:ee:rr:ss:22:3333:221
zz:xxx:sss:ddd:aaa:f
w:e:r:q:f:g:ghh:h:f:f:f:f
tihuan:ww:ee:rr:ss:22:3333:221
w:e:r:q:f:g:ghh:h:f:f:f:f
tihuan:ww:ee:rr:ss:22:3333:221
zz:xxx:sss:ddd:aaa:f
tihuan:ww:ee:rr:ss:22:3333:221

这里使用的是awk里面的查找替换功能,即gsub函数。
gsub的格式如下:

gsub(“替换对象”,“替换成什么内容”,哪一列)

注意:

  • gsub与后面的括号之间不能有空格。
  • 替换对象、替换成什么内容以及哪一列之间要用逗号分隔开。
  • 替换对象的外面要有双引号或双斜线包裹起来,即“替换对象”或/替换对象/。
  • 替换成什么内容就只能用双引号包裹起来了,即“替换成什么内容”。
  • 最后一个是哪一列,这个是可以省略的,省略的时候表示要替换整行的内容,相当于是写上了$0。

案例6:取出eth0网卡对应的ip地址。

本地机器的ip信息如下

bash-5.0# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:26 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1968 (1.9 KiB)  TX bytes:246 (246.0 B)

本例的方法特别多,这里仅使用awk给出常见的实现。

方法1
bash-5.0# ifconfig eth0 |awk -F "(addr:)|(  Bcast:)" 'NR==2{print $2}'
172.17.0.2
说明:

-F"(addr:)|(Bcast:)"这个还是比较容易理解的,我们的目标是取得ip,本例是10.0.0.8,ip的左边是“addr:”,右边是“Bcast:”,左边分隔,即把“addr:”作为分隔符,右边分隔,即把“Bcast:”作为分隔符,剩下中间的ip就是我们想要的。
但是还需要一个条件,ip地址在第二行所以使用NR==2来表示。

方法2
bash-5.0# ifconfig eth0|awk -F "[ :]+"  'NR==2{print $4}'
172.17.0.2

在这里插入图片描述

说明:

172.17.0.2的左边挨着的是冒号,因此可以用冒号作为分隔符,即-F":“。
172.17.0.2的右边挨着的是空格,因此可以用空格作为分隔符,即-F”“。
但是行的最左边是多个空格又该怎么处理呢?
很简单,可以用正则表达式的加号(+),表示重复前面一个字符一次或一次以上。
结合起来就是,-F”[:]+"以单个或连续的空格或冒号或者它们的组合为分隔符,最后就可以获得我们想要的ip地址。

案例7:将域名取出并根据域名进行计数排序处理(百度和搜狐面试题):

bash-5.0# cat domainTest.txt
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html

1.取出域名

bash-5.0# awk -F '/' '{print $3}' domainTest.txt
www.etiantian.org
www.etiantian.org
post.etiantian.org
mp3.etiantian.org
www.etiantian.org
post.etiantian.org

2.排序

bash-5.0# awk -F '/' '{print $3}' domainTest.txt | sort
mp3.etiantian.org
post.etiantian.org
post.etiantian.org
www.etiantian.org
www.etiantian.org
www.etiantian.org

3.去重计数

 awk -F '/' '{print $3}' domainTest.txt | sort | uniq -c
      1 mp3.etiantian.org
      2 post.etiantian.org
      3 www.etiantian.org
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荷逸同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值