awk经典实战、正则表达式

目录

1.筛选给定时间范围内的日志

2.统计独立IP

案列

需求

代码

运行结果

3.根据某字段去重

案例

运行结果

4.正则表达式

1)认识正则

2)匹配字符

3)匹配次数

4)位置锚定:定位出现的位置

5)分组和后向引用


1.筛选给定时间范围内的日志

grep/sed/awk用正则去筛选日志时,如果要精确到小时、分钟、秒,则非常难以实现。

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

root@Ubuntu:~# # 2019-11-10 03:42:40转换成epoch为1970-01-01 00:00:00

root@Ubuntu:~# awk 'BEGIN{print mktime("2023 08 05 08 44 40")}'

1691196280

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

下面strptime1()实现的是将2023-08-04-12-40-40 29T03:42:40+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。

可以利用patsplit来取时间中的数字

root@Ubuntu:~# vim demo.awk

root@Ubuntu:~# cat demo.awk

BEGIN{

#要筛选什么时间的日志,将其时间构建成epoch值

which_time = mktime("2023 08 04 22 40 29")

}

{

#取出日志的日期时间字符串部分

#match($0,"^.*\\[(.*)\\].*",arr)

#将日期时间字符串转换为epoch值

tmp_time = strptime1(arr[1])

#通过比较epoch值来比较时间大小

if(tmp_time > wgich_time){print}

}

#构建的时间字符串格式为:"2023-08-04T12:40:40+08:00"

function strptime1(str ,arr,Y,M,D,H,m,S){

patsplit(str,arr,"[0-9]{1,4}")

Y=arr[1]

M=arr[2]

D=arr[3]

H=arr[4]

m=arr[5]

S=srr[6]

return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))

}

下面strptime2()实现的是将10/Nov/2023:23:53:44+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。

root@Ubuntu:~# vim dwmo.awk

root@Ubuntu:~# cat dwmo.awk

BEGIN{

要筛选什么时间的日志,将其时间构建成epoch值

which_time = mktime("2023 08 04 11 42 40")

}

{

取出日志中的日期时间字符串部分

match($0,"^.*\\[(.*)\\].*",arr)

将日期时间字符串转换为epoch值

tmp_time = strptime2(arr[1])

通过比较epoch值来比较时间大小

if(tmp_time > which_time){

print

}

}

构建的时间字符串格式为:"10/Nov/2023: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 2023 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]

}

2.统计独立IP

? url 访问IP 访问时间 访问人

案列

a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest

b.com.cn|202.109.134.23|2015-11-20 20:34:48|guest

c.com.cn|202.109.134.24|2015-11-20 20:34:48|guest

a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest

a.com.cn|202.109.134.24|2015-11-20 20:34:43|guest

b.com.cn|202.109.134.25|2015-11-20 20:34:48|guest

需求

统计每个URL的独立访问IP有多少个(去重),并且要为每个URL保存一个对应的文件,得到的结果类似

代码

BEGIN{

FS="|"

}

!arr[$1,$2]++{

arr1[$1]++

}

END{

for(i in arr1) {

print i, arr1[i] >(i".txt")

}

}
root@Ubuntu:~# awk -f 1.awk demo3.txt

root@Ubuntu:~# ls -al

总计 92

drwx------ 6 root root 4096 8月 5 09:50 .

drwxr-xr-x 19 root root 4096 8月 3 17:32 ..

-rw-r--r-- 1 root root 109 8月 5 09:50 1.awk
-rw-r--r-- 1 root root 11 8月 5 09:50 a.com.cn.txt

-rw-r--r-- 1 root root 25 8月 4 10:19 awk

-rw------- 1 root root 973 8月 4 17:19 .bash_history

-rw-r--r-- 1 root root 3106 10月 17 2022 .bashrc
-rw-r--r-- 1 root root 11 8月 5 09:50 b.com.cn.txt

drwx------ 2 root root 4096 8月 3 18:13 .cache
-rw-r--r-- 1 root root 11 8月 5 09:50 c.com.cn.txt

drwxr-xr-x 2 root root 4096 8月 4 17:26 .cookiecutters

-rw-r--r-- 1 root root 566 8月 4 16:17 demo1.txt

-rw-r--r-- 1 root root 250 8月 5 09:24 demo2.txt

-rw-r--r-- 1 root root 300 8月 5 09:35 demo3.txt

-rw-r--r-- 1 root root 611 8月 5 09:08 demo.awk

-rw-r--r-- 1 root root 984 8月 5 08:50 dwmo.awk

-rw------- 1 root root 20 8月 4 10:37 .lesshst

-rw-r--r-- 1 root root 161 10月 17 2022 .profile

drwx------ 5 root root 4096 8月 3 17:39 snap

drwx------ 2 root root 4096 8月 3 17:39 .ssh

-rw------- 1 root root 8280 8月 5 09:50 .viminfo

运行结果

root@Ubuntu:~# cat a.com.cn.txt

a.com.cn 2

root@Ubuntu:~# cat b.com.cn.txt

b.com.cn 2

root@Ubuntu:~# cat c.com.cn.txt

c.com.cn 1

3.根据某字段去重

去掉uid=xxx重复的行

案例

2019-01-13_12:00_index?uid=123

2019-01-13_13:00_index?uid=123

2019-01-13_14:00_index?uid=333

2019-01-13_15:00_index?uid=9710

2019-01-14_12:00_index?uid=123

2019-01-14_13:00_index?uid=123

2019-01-15_14:00_index?uid=333

2019-01-16_15:00_index?uid=9710

首先利用uid去重,我们需要利用?进行划分,然后将uid=xxx保存在数组中,这是判断重复的依据

然后统计uid出现次数,第一次出现统计,第二次不统计

运行结果

root@Ubuntu:~# vim demo2.txt

root@Ubuntu:~# awk -F"?" '!arr[$2]++{print}' demo2.txt

2019-01-13_12:00_index?uid=123

2019-01-13_14:00_index?uid=333

2019-01-13_15:00_index?uid=9710

4.正则表达式

1)认识正则

(1)介绍

正则表达式应用广泛,在绝大多数的编程语言都可以完美应用,在Linux中,也有着极大的用处。

使用正则表达式,可以有效的筛选出需要的文本,然后结合相应的支持的工具或语言,完成任务需求。

在本篇博客中,我们使用grep/egrep来完成对正则表达式的调用

(2)正则表达式类型

正则表达式可以使用正则表达式引擎实现,正则表达式引擎是解释正则表达式模式并使用这些模式匹配文本的基础软件。

在Linux中,常用的正则表达式有:

  • POSIX 基本正则表达式(BRE)引擎

  • POSIX 扩展正则表达式(BRE)引擎

2)匹配字符

  • . 匹配任意单个字符,不能匹配空行

  • [] 匹配指定范围内的任意单个字符

  • [^] 取反

  • [:alnum:] 或 [0-9a-zA-Z]

  • [:alpha:] 或 [a-zA-Z]

  • [:upper:] 或 [A-Z]

  • [:lower:] 或 [a-z]

  • [:blank:] 空白字符(空格和制表符)

  • [:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)

  • [:cntrl:] 不可打印的控制字符(退格、删除、警铃...)

  • [:digit:] 十进制数字 或[0-9]

  • [:xdigit:]十六进制数字

  • [:graph:] 可打印的非空白字符

  • [:print:] 可打印字符

  • [:punct:] 标点符号

3)匹配次数

  • * 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配

  • .* 任意前面长度的任意字符,不包括0次

  • \? 匹配其前面的字符0 或 1次

  • + 匹配其前面的字符至少1次

  • {n} 匹配前面的字符n次

  • {m,n} 匹配前面的字符至少m 次,至多n次

  • {,n} 匹配前面的字符至多n次

  • {n,} 匹配前面的字符至少n次

4)位置锚定:定位出现的位置

  • ^ 行首锚定,用于模式的最左侧

  • $ 行尾锚定,用于模式的最右侧

  • ^PATTERN$,用于模式匹配整行

  • ^$ 空行

  • ^[[:space:]].*$ 空白行

  • < 或 \b 词首锚定,用于单词模式的左侧

  • > 或 \b 词尾锚定;用于单词模式的右侧

  • <PATTERN>

5)分组和后向引用

① 分组:() 将一个或多个字符捆绑在一起,当作一个整体进行处理

分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3, ...

② 后向引用

引用前面的分组括号中的模式所匹配字符,而非模式本身

\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

\2 表示从左侧起第2个左括号以及与之匹配右括号之间的模式所匹配到的字符,以此类推

& 表示前面的分组中所有字

相关推荐
二十雨辰13 分钟前
[linux]docker基础
linux·运维·docker
Jason-河山1 小时前
【自动化更新,让商品信息跳舞】——利用API返回值的幽默编程之旅
运维·自动化
饮浊酒1 小时前
Linux操作系统 ------(3.文本编译器Vim)
linux·vim
lihuhelihu1 小时前
第3章 CentOS系统管理
linux·运维·服务器·计算机网络·ubuntu·centos·云计算
哲讯智能科技1 小时前
SAP Business One市场价格解析
运维·sap·erp
矛取矛求1 小时前
Linux系统性能调优技巧
linux
山东布谷科技官方1 小时前
布谷直播源码部署服务器关于数据库配置的详细说明
运维·服务器·数据库·直播系统源码·直播源码·直播系统搭建·直播软件开发
One_Blanks1 小时前
渗透测试-Linux基础(1)
linux·运维·安全
Perishell1 小时前
无人机避障——大疆与Airsim中的角速度信息订阅获取
linux·动态规划·无人机
爱吃喵的鲤鱼2 小时前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++