awk学习一之简单入门

awk 简介

awk是处理文本文件的一个应用程序,几乎所有 Linux 系统都自带这个程序。
原理:
它依次处理文件的每一行,并读取里面的每一个字段。

使用场景:
对于日志、CSV 那样的每行格式相同的文本文件,awk可能是最方便的工具。

awk其实不仅仅是工具软件,还是一种编程语言。不过,本文只介绍它的命令行用法。

基本用法

# 格式
$ awk [flags] '[range1] {动作1} [range2] {动作2} ...'' 文件名

说明:
范围:表示动作的执行范围、比如BEGIN、END、模式匹配/PATTERN/, 条件等;
动作:一般用{}包含;
注:使用单引号''来包含范围以及动作;

# 示例
$ awk '{print $0}' demo.txt

上面示例中,demo.txt是awk所要处理的文本文件。
前面单引号内部有一个大括号,里面就是每一行的处理动作print $0。
其中,print是打印命令,$0代表当前行,
因此上面命令的执行结果,就是把每一行原样打印出来。

请添加图片描述
请添加图片描述

$ echo ‘this is a test’ | awk ‘{print $0}’
this is a test
上面代码中,print $0就是把标准输入this is a test,重新打印了一遍。
awk会根据空格和制表符,将每一行分成若干字段,
依次用$1、$2、$3代表第一个字段、第二个字段、第三个字段等等。
$ echo ‘this is a test’ | awk ‘{print $3}’
a

参数

-F: file seperator; 指定域分隔符;

为了便于举例,我们把/etc/passwd文件保存成demo.txt。

root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync

用-F参数指定分隔符为冒号。然后,才能提取到它的第一个字段。
$ awk -F ':' '{ print $1 }' demo.txt
root
daemon
bin
sys
sync

变量

字段

$ + 数字表示某个字段
$0: 整行;
$1: 第一个字段;
$2: 第二个字段;

特殊字段

NF
变量NF(number of filed)表示当前行有多少个字段,
因此$NF就代表最后一个字段。$(NF-1)代表倒数第二个字段。

$ awk -F ':' '{print $1, $(NF-1)}' demo.txt
root /root
daemon /usr/sbin
bin /bin
sys /dev
sync /bin

上面代码中,print命令里面的逗号,表示输出的时候,两个部分之间使用空格分隔。

NR
变量NR(number of record)表示当前处理的是第几行。


$ awk -F ':' '{print NR ") " $1}' demo.txt
1) root
2) daemon
3) bin
4) sys
5) sync

其他变量

FILENAME:当前文件名,在一次性处理多个文件时非常有用;
FS:字段分隔符(field seperator),默认是空格和制表符。
RS:行分隔符(record seperator),用于分割每一行,默认是换行符。
OFS:输出字段的分隔符(output field seperator),用于打印时分隔字段,默认为空格。
ORS:输出记录的分隔符(output record seperator),用于打印时分隔记录,默认为换行符。
OFMT:数字输出的格式(output format),默认为%.6g。

FS

下面的两个命令是等价的 。
awk -F ':'  '{print $3}' file
awk 'BEGIN{FS=":"}{print $3}' file

如果你的文件既有用,分隔的,也有用:分割的,
FS甚至可以指定多个分隔符同时起作用。
FS="[,:|]"

NF

NF 列数。非常有用,比如,过滤一些列数不满足条件的内容。
awk -F, '{if(NF==3){print}}' file

NR

NR 行号,例如,下面两个命令是等价的。
cat -n file
awk '{print NR,$0}' file

OFS

OFS  指定输出内容的分割符,列数非常多的时候,简化操作。相似命令:
awk -F ':' '{print $1,"-",$2,"-",$4}' file
awk 'BEGIN{FS=":";OFS="-"}{print $1,$2,$4}' file

函数

awk还提供了一些内置函数,方便对原始数据的处理。

函数toupper()

函数toupper()用于将字符转为大写。

$ awk -F ':' '{ print toupper($1) }' demo.txt
ROOT
DAEMON
BIN
SYS
SYNC

其他函数

tolower():字符转为小写。
length():返回字符串长度。
substr():返回子字符串。
sin():正弦。
cos():余弦。
sqrt():平方根。
rand():随机数。

更多函数参考:awk官方内置函数

条件

awk允许指定输出条件,只输出符合条件的行。

输出条件要写在动作的前面, 如下所示:
$ awk ‘条件 {动作}’ 文件名

$ awk -F ':' '/usr/ {print $1}' demo.txt
root
daemon
bin
sys

上面代码中,print命令前面是一个正则表达式,只输出包含usr的行。

# 输出奇数行
$ awk -F ':' 'NR % 2 == 1 {print $1}' demo.txt
root
bin
sync

# 输出第三行以后的行
$ awk -F ':' 'NR >3 {print $1}' demo.txt
sys
sync
输出第一个字段等于指定值的行:

$ awk -F ':' '$1 == "root" {print $1}' demo.txt
root

$ awk -F ':' '$1 == "root" || $1 == "bin" {print $1}' demo.txt
root
bin

if 语句

awk提供了if结构,用于编写复杂的条件, 比如可以 if…else 来进行复杂的处理;

$ awk -F ':' '{if ($1 > "m") print $1}' demo.txt
root
sys
sync

输出第一个字段的第一个字符大于m的行。
$ awk -F ':' '{if ($1 > "m") print $1; else print "---"}' demo.txt
root
---
---
sys
sync

范例

netstat统计输出

采用awk统计netstat命令的一些网络状态,netstat的输出类似于:
请添加图片描述

第6列,标明了网络连接所处于的网络状态, 统计每个状态的个数;

netstat  -ant | 
awk ' \
    BEGIN{print  "State","Count" }  \
    /^tcp/ \
    { rt[$6]++ } \
    END{  for(i in rt){print i,rt[i]}  }'
    
上面的rt[$6]++,就已经默认定义了一个叫做rt的hash(array?),
里面的key是网络状态,而value是可以进行运算的(+-*/%)。

输出结果为:

State Count
LAST_ACK 1
LISTEN 64
CLOSE_WAIT 43
ESTABLISHED 719
SYN_SENT 5
TIME_WAIT 146

分析
请添加图片描述

  • BEGIN 开头部分,可选的。
    用来设置一些参数,输出一些表头,定义一些变量等
    上面的命令仅打印了一行信息而已。

  • END 结尾部分,可选的。
    用来计算一些汇总逻辑,或者输出这些内容
    上面的命令,使用简单的for循环,输出了数组rt中的内容。

  • Pattern 匹配部分,依然可选。
    用来匹配一些需要处理的行。上
    面的命令,只匹配tcp开头的行,其他的不进入处理。

  • Action 模块。
    主要逻辑体,按行处理,统计打印,都可以。

参考

http://www.ruanyifeng.com/blog/2018/11/awk.html

https://mp.weixin.qq.com/s?__biz=MzA4MTc4NTUxNQ==&mid=2650519843&idx=1&sn=fe4a5c405a35b42a850054eb4283ff40&chksm=8780bee7b0f737f194d356c155b67d19be574454adcb8ce0d16c84e6246a718c9cf29c223512&scene=21#wechat_redirect
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值