從日誌檔案中獲取特定信息

從日誌檔案中獲取特定信息

我想從日誌檔案中獲取一些部分,我嘗試剪切請求部分以獲取用戶、模組、操作、doAjax 和 ajaxAction

例如,我有

195.xx.x.x - - [25/Apr/2017:09:60:xx +0200] "POST /userx/index.php?m=contacts&a=form&...
192.xx.x.x - - [25/Apr/2017:09:45:xx +0200] "POST /usery/index.php?m=customer&doajax=request&action=getContacts...
197.xx.x.x - - [25/Apr/2017:09:20:xx +0200] "GET /userx/index.php?m=meeting&doajax=date&id=3

我想要:

[user]|[module]|[action]|[doAjax]|[ajaxAction] 
usery  contacts  form     null     null
userx  customer  null     request  getContacts
userz  meeting   null     date     null

在哪裡:

userx --> user  
m=xxx -->module   
a=xxx -->action  
doajax=xxx-->doAjax   
action=xxx-->ajaxAction  

我嘗試使用awk, set but for 只剪切第七列,我可以在其中使用以下命令找到我的請求:

awk '{printf $7; next ; }' logfile

那麼,在列印我的請求後,我該如何提取使用者、模組、操作、doAjax 和 ajaxAction 呢?

答案1

Perl「一行」:

$ perl -lne '
BEGIN{
    printf "%-10s%-10s%-10s%-10s%-15s\n", qw([user] [module] [action] [doAjax] [ajaxAction]);
} 
$usr = $mde = $act = $doAj = $ajAc = "null"; 
$usr=$1 if m|\s/([^/]+)/|; 
$mde=$1 if /m=(.+?)(&|$)/; 
$act=$1 if /a=(.+?)(&|$)/; 
$doAj=$1 if /doajax=(.+?)(&|$)/; 
$ajAc=$1 if /action=(.+?)(&|$)/; 
printf "%-10s%-10s%-10s%-10s%-15s\n", ($usr,$mde,$act,$doAj,$ajAc)' file 
[user]    [module]  [action]  [doAjax]  [ajaxAction]   
userx     contacts  form      null      null           
usery     customer  null      request   getContacts    
userx     meeting   null      date      null           

這裡的基本技巧是搜尋標識 URL 部分的每個字串,如果找到,則為其設定相應的變數。在每種情況下,我們都會尋找標識符,後面跟著一個=(例如m=),然後是一個&或行尾(&|$)。因為匹配的部分放在括號中(例如m=(.+?)),所以我們可以將其稱為 ,$2這就是每個變數中保存的內容。

如果您確實需要|作為分隔符,並且不反對它會使輸出的可讀性較差,您可以使用它:

$ perl -lne '
BEGIN{
    printf "%s|%s|%s|%s|%s\n", qw([user] [module] [action] [doAjax] [ajaxAction]);
} 
$usr = $mde = $act = $doAj = $ajAc = "null"; 
$usr=$1 if m|\s/([^/]+)/|; 
$mde=$1 if /m=(.+?)(&|$)/; 
$act=$1 if /a=(.+?)(&|$)/; 
$doAj=$1 if /doajax=(.+?)(&|$)/; 
$ajAc=$1 if /action=(.+?)(&|$)/; 
print join "|", ($usr,$mde,$act,$doAj,$ajAc)' file 
[user]|[module]|[action]|[doAjax]|[ajaxAction]
userx|contacts|form|null|null
usery|customer|null|request|getContacts
userx|meeting|null|date|null

更好的(更易讀的輸出)方法是使用printf

答案2

如果您喜歡在 awk 中執行此操作,可以執行以下操作。拆分允許您使用任何字段分隔符號拆分字串。

awk  '{split($7,a,"/"); split(a[3],b,"m="); split(b[2],c,"&"); split(c[2],d,"="); print a[2], c[1], d[1], d[2] }' logfile

這會產生所需的列。

userx contacts a form
usery customer doajax request
userx meeting doajax date

剩下的步驟就是格式化。 awk 中的陣列是關聯的,可以用字串索引 - 請參閱這裡。您可以執行以下操作;此處,op(輸出的縮寫)被初始化為 null。然後,我們設定op[d[1]]=d[2].

awk  '{split($7,a,"/"); split(a[3],b,"m="); split(b[2],c,"&"); split(c[2],d,"="); op["a"]="null"; op["doajax"]="null"; op["ajaxaction"]="null"; op[d[1]]=d[2];print a[2], c[1], op["a"], op["doajax"], op["ajaxaction"] }' junk.txt 

[修改為]

awk  '{split($7,a,"/"); split(a[3],b,"m="); split(b[2],c,"&"); split(c[2],d,"="); op["a"]="null"; op["doajax"]="null"; op["action"]="null"; op[d[1]]=d[2]; split(c[3],f,"="); split(f[2],g,"."); op[f[1]]=g[1]; print a[2], c[1], op["a"], op["doajax"], op["action"] }' junk.txt 

輸出如下

userx contacts form null null
usery customer null request getContacts
userx meeting null date null

答案3

perl -lane '
BEGIN {
   print $H = join "|", map { s/.*/[$&]/r } @H = qw/user module action doAjax ajaxAction/;
   pos($H) = 0;
   push(@pos, pos($H)-$p), $p=pos($H) while $H =~ /\[/g;
   $fmt = join "", map { "\%-${_}s" } @pos[1..$#pos], length($H)-$p;
}

   my(%h, %H) = $F[-1] =~ /[?&]\K([^=]+)=([^&]+)/g;
   @H{@H} = ($F[-1] =~ m|^/([^/]+)|, @h{qw/m a doajax action/});
   print sprintf $fmt, map { $H{$_} // "null" } @H;
' logfile

結果

[user]|[module]|[action]|[doAjax]|[ajaxAction]
userx  contacts form     null     null
usery  customer null     request  getContacts
userx  meeting  null     date     null

解釋

  1. Perl 選項:

    -l 使ORS = RS = \n

    -a將欄位儲存在@F透過拆分目前記錄所獲得的數組中/\s+/,因此例如,$F[0] => $1, $F[1] => $2, ..., $F[-1] => $NF

    -n 設定一個隱式循環,逐行讀取輸入文件,除非要求,否則不輸出。

  2. 開始塊:

    首先我們列印標題。然後我們根據 header 動態確定格式。對於讀取的每一行,我們設定一個哈希 %h,其鍵是=之前的字串,值是=之後的字串。要查看的字串緊鄰 ?或 & 位於左側,& 位於右側。接下來,我們設定另一個雜湊 %H,其鍵被重新命名為 %h 雜湊的版本。接下來,我們根據 BEGIN 區塊中計算的格式列印雜湊值。

相關內容