awk的基础

目录

awk

awk的语法

1.从命令行读取程序脚本

2.使用数据字段变量

3.在脚本中使用多个命令

4.从文件中读取程序 -f

5.在数据处理前运行脚本

6.在处理数据后运行脚本


awk

awk程序是Unix中的原始awk程序的GNU版本。 awk程序让流编辑迈上了一个新的台阶,它提供了一种编程语言而不只是编辑器命令

awk的特点

  • 定义变量来保存数据;
  • 使用算术和字符串操作符来处理数据;
  • 使用结构化编程概念(比如if-then语句和循环)来为数据处理增加处理逻辑;
  • 通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告。

awk的语法

awk options program file '{ }'

选项options

描述

-F fs

指定行中划分数据字段的字段分隔符

-f file

从指定的文件中读取程序

-v var=value

定义awk程序中的一个变量及其默认值

-mf N

指定要处理的数据文件中的最大字段数

-mr N

指定数据文件中的最大数据行数

-W keyword

指定awk的兼容模式或者警告等级

awk程序脚本用一对花括号来定义。你必须将脚本命令放到两个花括号{ }中。如果你错误地使用了圆括号来包含awk脚本,就会得到一条错误提示

1.从命令行读取程序脚本

print命令。这个命令名副其实:它会将文本打印到STDOUT

[root@localhost fuxi]# awk '{print "Hello World"}'

Hello World

Hello World

Hello World

如果尝试运行这个命令,你可能会有些失望,因为什么都不会发生。原因在于没有

在命令行上指定文件名,所以awk程序会从STDIN接收数据。在运行这个程序时,它会一直等

待从STDIN输入的文本

如果你输入一行文本并按下回车键, awk会对这行文本运行一遍程序脚本。跟sed编辑器一

样, awk程序会针对数据流中的每行文本执行程序脚本。由于程序脚本被设为显示一行固定的

文本字符串,因此不管你在数据流中输入什么文本,都会得到同样的文本输出

2.使用数据字段变量

默认情况下, awk会将如下变量分配给它在文本行中发现的数据字段

  • $0代表整个文本行;
  • $1代表文本行中的第1个数据字段;
  • $2代表文本行中的第2个数据字段;
  • $n代表文本行中的第n个数据字段。

在文本行中,每个数据字段都是通过字段分隔符划分的。 awk在读取一行文本时,会用预定义

的字段分隔符划分每个数据字段。 awk中默认的字段分隔符是任意的空白字符(例如空格或制

表符)

[root@localhost fuxi]# cat data.txt 
This is line number 1
This is line number 2
This is line number 3
This is line number 4
[root@localhost fuxi]# awk '{print $5}' data.txt
1
2
3
4

也可以通过 -F 选项自定义分隔符

3.在脚本中使用多个命令

和sed类似  可以使用分号 ; 来分隔命令

[root@localhost fuxi]# echo "my name is kaka" | awk '{$4="fufu";print $0 }'
my name is fufu

或者使用ps2  单引号 '' 来包括一堆的命令

[root@localhost fuxi]# echo "my name is kaka" | awk '{                                              
$4="fufu"
print $0}'
my name is fufu

4.从文件中读取程序 -f

[root@localhost fuxi]# awk -F: -f script.awk /etc/passwd | head -3
root's home directory is /root
bin's home directory is /bin
daemon's home directory is /sbin

5.在数据处理前运行脚本

BEGIN

会强制awk在读取数据前执行BEGIN关键字后指定的程序脚本

[root@localhost fuxi]# awk 'BEGIN {print "Hellow World !"}'
Hellow World !

这次print命令会在读取数据前显示文本。

[root@localhost fuxi]# cat data.txt 
This is line number 1
This is line number 2
This is line number 3
This is line number 4
[root@localhost fuxi]# awk 'BEGIN {print "The data File Contents:"} {print $5}' data.txt 
The data File Contents:
1
2
3
4

6.在处理数据后运行脚本

与BEGIN关键字类似, END关键字允许你指定一个程序脚本, awk会在读完数据后执行它

[root@localhost fuxi]# cat data.txt 
This is line number 1
This is line number 2
This is line number 3
This is line number 4
[root@localhost fuxi]# awk 'BEGIN {print "The data File Contents:"} {print $5} END{print "END of File"}' data.txt 
The data File Contents:
1
2
3
4
END of File

筛选给定时间范围内的日志的例子

awk提供了一个mktime()函数,它可以将时间转换成epoch时间值

[root@localhost awk]# awk 'BEGIN{print mktime("2019 11 10 03 42 40")}'
1573328560

借此,可以取得日志中的时间字符串部分,再将它们的年、月、日、时、分、秒都取出来,然后放入mktime()构建成对应的epoch值。因为epoch值是数值,所以可以比较大小,从而决定时间的大小

BEGIN{
  # 要筛选什么时间的日志,将其时间构建成epoch值
  which_time = mktime("2019 11 10 03 42 40")
}

{
  # 取出日志中的日期时间字符串部分
  match($0,"^.*\\[(.*)\\].*",arr)

  # 将日期时间字符串转换为epoch值
  tmp_time = strptime2(arr[1])

  # 通过比较epoch值来比较时间大小
  if(tmp_time > which_time){
    print 
  }
}

# 构建的时间字符串格式为:"10/Nov/2019:23:53:44+08:00"
function strptime2(str,dt_str,arr,Y,M,D,H,m,S) {
  dt_str = gensub("[/:+]"," ","g",str)
  # dt_sr = "10 Nov 2019 23 53 44 08 00"
  split(dt_str,arr," ")
  Y=arr[3]
  M=mon_map(arr[2])
  D=arr[1]
  H=arr[4]
  m=arr[5]
  S=arr[6]
  return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
}

function mon_map(str,mons){
  mons["Jan"]=1
  mons["Feb"]=2
  mons["Mar"]=3
  mons["Apr"]=4
  mons["May"]=5
  mons["Jun"]=6
  mons["Jul"]=7
  mons["Aug"]=8
  mons["Sep"]=9
  mons["Oct"]=10
  mons["Nov"]=11
  mons["Dec"]=12
  return mons[str]
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值