awk命令使用实践

语法

awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)
复制代码

常用参数

-F fs   fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:,多个分隔符(例如:和制表符)为awk -F '[:\t]' 或者 '[:|\t]' 或者 '[":"|"\t"]',表示没发现区别
-v var=value   赋值一个用户定义变量,将外部变量传递给awk
-f scripfile  从脚本文件中读取awk命令
-m[fr] val   对val值设置内在限制,-mf选项限制分配给val的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
复制代码

摘要介绍

日常Linux流程,遇见不会的命令,先 man command,所以 awk 的文档介绍是这么写的 mawk - pattern scanning and text processing language 用我的菜鸡英语翻译就是:模式扫描和文本处理语言。

是的,awk 并不是一个二进制程序命令,而是一门脚本语言,主要用来匹配处理文本,就像 bash 一样,同理 bash 有多个解释器: zsh, fish 等一样,awk 也有,例如我 man awk 看到的是 mawk,我的是Ubuntu16.04系统。因此既然 awk 是语言,mawk 是解释器而已,所以我们的操作可以是将 awk 代码直接在终端中使用,就像bashecho 'hello world'一样,也可以写成一个脚本,通过 awk -f filename 一样执行。

awk的处理方式是从输入流从逐行读取文本,然后进行 模式-动作 流程,即

pattern    { action }
复制代码

小例子:

$ ls | awk '1 < 2 {print "废话"}'
废话
复制代码

这里的 1 < 2 就是 pattern 了,而 action 要包裹在 {} 里面。

使用实践-剪切获取ifconfig中的ip地址

文本如下

$ ifconfig wlp8s0 
wlp8s0    Link encap:Ethernet  HWaddr 5c:93:a2:76:e5:c1  
          inet addr:192.168.123.111  Bcast:192.168.123.255  Mask:255.255.255.0
          inet6 addr: fe80::44cd:39be:6aea:d61a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:698409 errors:0 dropped:0 overruns:0 frame:0
          TX packets:353304 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:949454893 (949.4 MB)  TX bytes:38261895 (38.2 MB)
复制代码

简单的剪切思路,先通过正则表达式获取ip地址那一行,awk默认的分隔符是空格,所以很明显我们的ip地址在第二列。

$ ifconfig wlp8s0 | awk '$0 ~ /inet addr/ {printf $2}'
addr:192.168.123.111
复制代码

解释如下:

  • $0 表示当前读取的整行,上面文本有
  • ~ 表示开启正则匹配
  • /inet addr/ 正则匹配内容,表达式要写在//中间。即/pattern/
  • {print $2} 表示匹配成功的话打印当前行的第二列。$2是内键变量,参考下面附录

接下来就很明显了,针对剪切出来的 addr:192.168.123.111 我们只需要以 : 为分隔符打印第二列就可以了。命令如下:

ifconfig wlp8s0 | awk '$0 ~ /inet addr/ {print $2}' | awk -F: '{print $2}'
复制代码

小提示:

  • 当把awk代码直接放在终端中使用时,建议使用 ' 而不是 " 包括起来,因为 " 可能会被bash解析了变量$0之类
  • printprintf的区别在于printf可以格式化输出,但是print自带换行

printf 示例如下

# 打印行号
$ ls / | awk '{printf "%d  %s\n", NR, $0}' 
行号:1  bin
行号:2  boot
行号:3  cdrom
行号:4  dev
行号:5  etc
行号:6  home
行号:7  initrd.img
行号:8  initrd.img.old
行号:9  lib
行号:10  lib64
行号:11  lost+found
行号:12  media
行号:13  mnt
行号:14  opt
行号:15  proc
行号:16  root
行号:17  run
行号:18  sbin
行号:19  snap
行号:20  srv
行号:21  sys
行号:22  tmp
行号:23  usr
行号:24  var
行号:25  vmlinuz
行号:26  vmlinuz.old
复制代码

事实上这用 nl 命令即可了。

ls / | nl
复制代码

附录-内键变量

变量描述
$n当前记录的第n个字段,字段间由FS分隔
$0完整的输入记录
ARGC命令行参数的数目
ARGIND命令行中当前文件的位置(从0开始算)
ARGV包含命令行参数的数组
CONVFMT数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO最后一个系统错误的描述
FIELDWIDTHS字段宽度列表(用空格键分隔)
FILENAME当前文件名
FNR各文件分别计数的行号
FS字段分隔符(默认是任何空格)
IGNORECASE如果为真,则进行忽略大小写的匹配
NF一条记录的字段的数目
NR已经读出的记录数,就是行号,从1开始
OFMT数字的输出格式(默认值是%.6g)
OFS输出记录分隔符(输出换行符),输出时用指定的符号代替换行符
ORS输出记录分隔符(默认值是一个换行符)
RLENGTH由match函数所匹配的字符串的长度
RS记录分隔符(默认是一个换行符)
RSTART由match函数所匹配的字符串的第一个位置
SUBSEP数组下标分隔符(默认值是/034)

悄悄放个个人博客地址 feng

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值