awk命令分析日志的簡單筆記


awk是一個文本分析工具,可以用來進行流量日志分析

之前無意中看到了這個命令,簡單記一下筆記 ,在打線下的時候可能會有用

awk有3個不同版本: awk、nawk和gawk,未作特別說明,一般指gawk。

 

有三種方式調用awk

1.命令行方式 awk [options] 'script' filename 其中,script 是真正awk命令,[-F域分隔符]是可選的。filename 是待處理的文件。 在awk中,文件的每一行中,由域分隔符分開的每一項稱為一個域。通常,在不指名-F域分隔符的情況下,默認的域分隔符是空格。
2.shell腳本方式 將所有的awk命令插入一個文件,並使awk程序可執行,然后awk命令解釋器作為腳本的首行,一遍通過鍵入腳本名稱來調用。 相當於shell腳本首行的:#!/bin/sh 可以換成:#!/bin/awk 3.將所有的awk命令插入一個單獨文件,然后調用: awk -f scriptfile  filename 其中,-f選項加載awk-script-file中的awk腳本

options 是命令選項 -- 比如幾個常用命令選項

  -F xx  以xx為分隔符,awk的默認分隔符為空格   例如 -F ':' 這樣

  -f scriptfile  從腳本文件中讀取awk命令  這時候就不需要后面的'script'了 

  -v var=value   賦值一個用戶定義變量,將外部變量傳遞給awk

script  則是如何對文本進行處理,支持正則表達式/xxx/,關系表達式即字符串或數字的比較測試,模式匹配表達式--用運算符~(匹配)和~!(不匹配)

  以及     BEGIN{ commands } pattern{ commands } END{ commands } 這三種語句塊

  BEGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中。

  END語句塊在awk從輸入流中讀取完所有的行之后即被執行,比如打印所有行的分析結果這類信息匯總都是在END語句塊中完成,它也是一個可選語句塊。

  pattern語句塊中的通用命令是最重要的部分,它也是可選的。如果沒有提供pattern語句塊,則默認執行{ print },即打印每一個讀取到的行,awk讀取的每一行都會執行該語句塊。

filenames則是要處理的文件名,可以用 |  將之前命令的輸出直接用awk處理,就不需要filenames了,也可以將wak的輸出通過 |  讓head和tail命令來處理

 

 

內置變量

說明:[A][N][P][G]表示第一個支持變量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk

$n 當前記錄的第n個字段,比如n為1表示第一個字段,n為2表示第二個字段。 $0 這個變量包含執行過程中當前行的文本內容。 [N] ARGC 命令行參數的數目。 [G] ARGIND 命令行中當前文件的位置(從0開始算)。 [N] ARGV 包含命令行參數的數組。 [G] CONVFMT 數字轉換格式(默認值為%.6g)。 [P] ENVIRON 環境變量關聯數組。 [N] ERRNO 最后一個系統錯誤的描述。 [G] FIELDWIDTHS 字段寬度列表(用空格鍵分隔)。 [A] FILENAME 當前輸入文件的名。 [P] FNR 同NR,但相對於當前文件。 [A] FS 字段分隔符(默認是任何空格)。 [G] IGNORECASE 如果為真,則進行忽略大小寫的匹配。 [A] NF 表示字段數,在執行過程中對應於當前的字段數。 [A] NR 表示記錄數,在執行過程中對應於當前的行號。 [A] OFMT 數字的輸出格式(默認值是%.6g)。 [A] OFS 輸出字段分隔符(默認值是一個空格)。 [A] ORS 輸出記錄分隔符(默認值是一個換行符)。 [A] RS 記錄分隔符(默認是一個換行符)。 [N] RSTART 由match函數所匹配的字符串的第一個位置。 [N] RLENGTH 由match函數所匹配的字符串的長度。 [N] SUBSEP 數組下標分隔符(默認值是34)。

 

輸出函數

awk中同時提供了print和printf兩種打印輸出的函數。

其中print函數的參數可以是變量、數值或者字符串。字符串必須用雙引號引用,參數用逗號分隔。如果沒有逗號,參數就串聯在一起而無法區分。這里,逗號的作用與輸出文件的分隔符的作用是一樣的,只是后者是空格而已。

printf函數,其用法和c語言中printf基本相似,可以格式化字符串,輸出復雜時,printf更加好用,代碼更易懂

 

簡單函數用法

打開外部文件 close函數

awk 'BEGIN{while("cat /etc/passwd"|getline){print $0;};close("/etc/passwd");}'  

逐行讀取外部文件內容 getline

awk 'BEGIN{while(getline < "/etc/passwd"){print $0;};close("/etc/passwd");}'  

調用外部應用程序 system函數

awk 'BEGIN{b=system("ls -al");print b;}'

 

字符串操作

查找字符串  index函數

awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}'  

正則表達式查找匹配

awk 'BEGIN{info="this is a test2010test!";print match(info,/[0-9]+/)?"ok":"no found";}'  

字符串截取

awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}'  

字符串分割

awk 'BEGIN{info="this is a test";split(info,tA," ");print length(tA);for(k in tA){print k,tA[k];}}'  

 


 

去實驗吧隨便找了個日志的題目 然后拿日志過來試一試

不知道為什么突然上傳不了圖片了只有貼一下數據 簡單測試一下

root@ubuntu:~# cat log | head -10
192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET / HTTP/1.1" 302 -
192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET /xampp/ HTTP/1.1" 302 -
192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET /xampp/splash.php HTTP/1.1" 200 1321
192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET /xampp/xampp.css HTTP/1.1" 200 3991
192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET /xampp/img/blank.gif HTTP/1.1" 200 43
192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET /xampp/img/xampp-logo.jpg HTTP/1.1" 200 19738
192.168.1.2 - - [16/Dec/2010:01:21:44 +0800] "GET /xampp/lang.php?zh HTTP/1.1" 302 -
192.168.1.2 - - [16/Dec/2010:01:21:44 +0800] "GET /xampp/index.php HTTP/1.1" 200 589
192.168.1.2 - - [16/Dec/2010:01:21:44 +0800] "GET /xampp/head.php HTTP/1.1" 200 1362
192.168.1.2 - - [16/Dec/2010:01:21:44 +0800] "GET /xampp/start.php HTTP/1.1" 200 534

 用 / 分割 輸出第一部分

root@ubuntu:~# awk -F '/'  '{print $1}' log | head -10
192.168.1.2 - - [16
192.168.1.2 - - [16
192.168.1.2 - - [16
192.168.1.2 - - [16
192.168.1.2 - - [16
192.168.1.2 - - [16
192.168.1.2 - - [16
192.168.1.2 - - [16
192.168.1.2 - - [16
192.168.1.2 - - [16

用-分割 輸出第一部分和最后一部分

root@ubuntu:~# awk -F '-'  '{print $1,$NF}' log | head -10
192.168.1.2  
192.168.1.2  
192.168.1.2   [16/Dec/2010:01:21:10 +0800] "GET /xampp/splash.php HTTP/1.1" 200 1321
192.168.1.2   [16/Dec/2010:01:21:10 +0800] "GET /xampp/xampp.css HTTP/1.1" 200 3991
192.168.1.2   [16/Dec/2010:01:21:10 +0800] "GET /xampp/img/blank.gif HTTP/1.1" 200 43
192.168.1.2  logo.jpg HTTP/1.1" 200 19738
192.168.1.2  
192.168.1.2   [16/Dec/2010:01:21:44 +0800] "GET /xampp/index.php HTTP/1.1" 200 589
192.168.1.2   [16/Dec/2010:01:21:44 +0800] "GET /xampp/head.php HTTP/1.1" 200 1362
192.168.1.2   [16/Dec/2010:01:21:44 +0800] "GET /xampp/start.php HTTP/1.1" 200 534

統計總行數

root@ubuntu:~# awk  'BEGIN{x=0;} {x++;} END{print x}' log 929 root@ubuntu:~# wc -l log 929 log

用/分割  把輸出的最后兩個部分寫進looog文件中

root@ubuntu:~# awk -F '/'  '{print $(NF-1),$NF}' log > looog awk: cmd. line:1: (FILENAME=log FNR=929) fatal: attempt to access field -1

root@ubuntu:~# cat looog | tail -10 pixel.gif HTTP 1.1" 404 1337 admin HTTP 1.1" 403 1110 login.php HTTP 1.1" 403 1110 robots.txt HTTP 1.1" 200 264 admin.php HTTP 1.1" 200 3763 pixel.gif HTTP 1.1" 404 1279 pixel.gif HTTP 1.1" 404 1279 admin.php HTTP 1.1" 200 3762 pixel.gif HTTP 1.1" 404 1279 pixel.gif HTTP 1.1" 404 1279

 

查找最后20行內有沒有 'php'   不用三元表達式就會直接返回位置

root@ubuntu:~# awk '{print index($0,"php")?"find":"no"}' log | tail -20 no no no no no find find find no no no find no find no no find no no no

用正則查找

root@ubuntu:~# awk '{print match($0,"php")?"find":"no"}' log | tail -20 no no no no no find find find no no no find no find no no find no no no

截取前五個字符

root@ubuntu:~# awk '{print substr($0,5,5)}' log | tail -10
168.1
168.1
168.1
168.1
168.1
168.1
168.1
168.1
168.1

 

 

參考資料

https://blog.csdn.net/u011204847/article/details/51205031

https://www.cnblogs.com/lyftest/p/7373453.html

http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM