目錄
1.篩選給定時(shí)間范圍內(nèi)的日志
?2.統(tǒng)計(jì)獨(dú)立IP
案列
?需求
代碼?
運(yùn)行結(jié)果
3.根據(jù)某字段去重
案例
運(yùn)行結(jié)果
4.正則表達(dá)式
1)認(rèn)識(shí)正則
?2)匹配字符
3)匹配次數(shù)?
4)位置錨定:定位出現(xiàn)的位置
5)分組和后向引用?
1.篩選給定時(shí)間范圍內(nèi)的日志
grep/sed/awk用正則去篩選日志時(shí),如果要精確到小時(shí)、分鐘、秒,則非常難以實(shí)現(xiàn)。
但是awk提供了mktime()函數(shù),它可以將時(shí)間轉(zhuǎn)換成epoch時(shí)間值。
root@Ubuntu:~# # 2019-11-10 03:42:40轉(zhuǎn)換成epoch為1970-01-01 00:00:00
root@Ubuntu:~# awk 'BEGIN{print mktime("2023 08 05 08 44 40")}'
1691196280
借此,可以取得日志中的時(shí)間字符串部分,再將它們的年、月、日、時(shí)、分、秒都取出來(lái),然后放入mktime()構(gòu)建成對(duì)應(yīng)的epoch值。因?yàn)閑poch值是數(shù)值,所以可以比較大小,從而決定時(shí)間的大小。
下面strptime1()實(shí)現(xiàn)的是將2023-08-04-12-40-40 29T03:42:40+08:00
格式的字符串轉(zhuǎn)換成epoch值,然后和which_time比較大小即可篩選出精確到秒的日志。
可以利用patsplit來(lái)取時(shí)間中的數(shù)字
root@Ubuntu:~# vim demo.awk
root@Ubuntu:~# cat demo.awk
BEGIN{
#要篩選什么時(shí)間的日志,將其時(shí)間構(gòu)建成epoch值
? ? ? ? which_time = mktime("2023 08 04 22 40 29")
}
{
#取出日志的日期時(shí)間字符串部分
? ? ? ? #match($0,"^.*\\[(.*)\\].*",arr)
#將日期時(shí)間字符串轉(zhuǎn)換為epoch值
? ? ? ? tmp_time = strptime1(arr[1])
#通過(guò)比較epoch值來(lái)比較時(shí)間大小
? ? ? ? if(tmp_time > wgich_time){print}
}
#構(gòu)建的時(shí)間字符串格式為:“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()實(shí)現(xiàn)的是將10/Nov/2023:23:53:44+08:00
格式的字符串轉(zhuǎn)換成epoch值,然后和which_time比較大小即可篩選出精確到秒的日志。
root@Ubuntu:~# vim dwmo.awk
root@Ubuntu:~# cat dwmo.awk
BEGIN{
? # 要篩選什么時(shí)間的日志,將其時(shí)間構(gòu)建成epoch值
? which_time = mktime("2023 08 04 11 42 40")
}{
? # 取出日志中的日期時(shí)間字符串部分
? match($0,"^.*\\[(.*)\\].*",arr)
??
? # 將日期時(shí)間字符串轉(zhuǎn)換為epoch值
? tmp_time = strptime2(arr[1])
??
? # 通過(guò)比較epoch值來(lái)比較時(shí)間大小
? if(tmp_time > which_time){
? ? print?
? }
}# 構(gòu)建的時(shí)間字符串格式為:"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.統(tǒng)計(jì)獨(dú)立IP
? url 訪問(wèn)IP 訪問(wèn)時(shí)間 訪問(wèn)人
案列
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
?需求
統(tǒng)計(jì)每個(gè)URL的獨(dú)立訪問(wèn)IP有多少個(gè)(去重),并且要為每個(gè)URL保存一個(gè)對(duì)應(yīng)的文件,得到的結(jié)果類似
代碼?
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
總計(jì) 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?
運(yùn)行結(jié)果
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.根據(jù)某字段去重
去掉uid=xxx
重復(fù)的行
案例
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去重,我們需要利用?進(jìn)行劃分,然后將uid=xxx保存在數(shù)組中,這是判斷重復(fù)的依據(jù)
然后統(tǒng)計(jì)uid出現(xiàn)次數(shù),第一次出現(xiàn)統(tǒng)計(jì),第二次不統(tǒng)計(jì)
運(yùn)行結(jié)果
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.正則表達(dá)式
1)認(rèn)識(shí)正則
(1)介紹
正則表達(dá)式應(yīng)用廣泛,在絕大多數(shù)的編程語(yǔ)言都可以完美應(yīng)用,在Linux中,也有著極大的用處。
使用正則表達(dá)式,可以有效的篩選出需要的文本,然后結(jié)合相應(yīng)的支持的工具或語(yǔ)言,完成任務(wù)需求。
在本篇博客中,我們使用grep/egrep來(lái)完成對(duì)正則表達(dá)式的調(diào)用
(2)正則表達(dá)式類型
正則表達(dá)式可以使用正則表達(dá)式引擎實(shí)現(xiàn),正則表達(dá)式引擎是解釋正則表達(dá)式模式并使用這些模式匹配文本的基礎(chǔ)軟件。
在Linux中,常用的正則表達(dá)式有:
POSIX 基本正則表達(dá)式(BRE)引擎
POSIX 擴(kuò)展正則表達(dá)式(BRE)引擎
?2)匹配字符
. 匹配任意單個(gè)字符,不能匹配空行
[] 匹配指定范圍內(nèi)的任意單個(gè)字符
[^] 取反
[:alnum:] 或 [0-9a-zA-Z]
[:alpha:] 或 [a-zA-Z]
[:upper:] 或 [A-Z]
[:lower:] 或 [a-z]
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范圍廣)
[:cntrl:] 不可打印的控制字符(退格、刪除、警鈴...)
[:digit:] 十進(jìn)制數(shù)字 或[0-9]
[:xdigit:]十六進(jìn)制數(shù)字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 標(biāo)點(diǎn)符號(hào)
3)匹配次數(shù)?
* 匹配前面的字符任意次,包括0次,貪婪模式:盡可能長(zhǎng)的匹配
.* 任意前面長(zhǎng)度的任意字符,不包括0次
\? 匹配其前面的字符0 或 1次
+ 匹配其前面的字符至少1次
{n} 匹配前面的字符n次
{m,n} 匹配前面的字符至少m 次,至多n次
{,n} 匹配前面的字符至多n次
{n,} 匹配前面的字符至少n次
?
4)位置錨定:定位出現(xiàn)的位置
^ 行首錨定,用于模式的最左側(cè)
$ 行尾錨定,用于模式的最右側(cè)
^PATTERN$,用于模式匹配整行
^$ 空行
^[[:space:]].*$ 空白行
< 或 \b 詞首錨定,用于單詞模式的左側(cè)
> 或 \b 詞尾錨定;用于單詞模式的右側(cè)
<PATTERN>
5)分組和后向引用?
① 分組:() 將一個(gè)或多個(gè)字符捆綁在一起,當(dāng)作一個(gè)整體進(jìn)行處理
分組括號(hào)中的模式匹配到的內(nèi)容會(huì)被正則表達(dá)式引擎記錄于內(nèi)部的變量中,這些變量的命名方式為: \1, \2, \3, ...
② 后向引用
引用前面的分組括號(hào)中的模式所匹配字符,而非模式本身
\1 表示從左側(cè)起第一個(gè)左括號(hào)以及與之匹配右括號(hào)之間的模式所匹配到的字符
\2 表示從左側(cè)起第2個(gè)左括號(hào)以及與之匹配右括號(hào)之間的模式所匹配到的字符,以此類推文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-639769.html
& 表示前面的分組中所有字文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-639769.html
到了這里,關(guān)于awk經(jīng)典實(shí)戰(zhàn)、正則表達(dá)式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!