2011-08-10 54 views
1

我有1000個由非常詳細的PHP腳本生成的日誌文件。一般結構如下使用sed/awk和正則表達式來處理日誌

###Unknown no of lines, which I want to ignore### 
================================================= 
$insert_vars['cdr_pkey']=17568 
$id<TAB>$g1<TAB>$i1<tab>rating1<TAB>$g2<TAB>$i2<tab>rating2 #<TAB>more $gX,$iX,$ratingX 
#numerical values of $id $g1 $i1 etc. separated by tab 
#numerical values of ---""--- 
#I do not know how many lines will be there (unique column is $id) 
================================================= 
###Unknown no of lines, which I want to ignore### 

我不得不處理這些日誌文件,並創建一個Excel工作表(我想csv格式)和數據彙報。我真的很糟糕,在Excel中,但我認爲像輸出東西:

cdr_pkey<TAB>id<TAB>g1<TAB>i1<TAB>rating1<TAB>g2<TAB>rating2 #and so on 
17568<TAB>1349<TAB>0.0004532<TAB>0.01320<TAB>2.014E-4<TAB>...#rest of numerical values 
17568<TAB>1364<TAB>...#values for id=1364 
17568<TAB>1321<TAB>...#values for id=1321 
... 
17569<TAB>1048<TAB>...#values for id=1048 
17569<TAB>1426<TAB>...#values for id=1426 
... 
... 

所以我cdr_pkey是在片唯一的列,併爲每個$cdr_pkey,我有多個$id S,各自有自己的一套$g1,$i1,$rating1...
經過測試這樣的格式,它可以通過excel讀取可以。現在我只想將它擴展到所有這1000個文件。
我只是不知道如何進一步進行。下一步是什麼?

+0

是日誌文件的結構是一致的(即所有日誌文件都包含在同一順序相同的列)?另外,你想要一個輸出文件還是每個輸入文件? – Tomalak

+0

是日誌文件結構是一致的。我想單個輸出文件。每個輸入文件都有唯一的'$ insert_vars ['cdr_pkey']',我想將所有文件與初始列結合爲'cdr_pkey' @Tomalak:謝謝 – Sudhi

回答

3

下面的bash腳本會做一些可能與你想要的相關的東西。當你說<TAB>時,它的參數是你的意思。我假設你的意思是ascii製表符,但如果你的日誌非常冗長,以至於他們拼寫出<TAB>,你需要相應地修改變量$WHAT_DID_YOU_MEAN_BY_TAB。請注意,這個劇本沒有什麼關於The Right Thing™的內容。它會將整個文件讀取到一個字符串變量中,根據日誌文件的大小,這可能甚至不可能。另一方面,如果你認爲這樣做更好,腳本可以很容易地修改爲兩次。

#!/bin/bash 

WHAT_DID_YOU_MEAN_BY_TAB='\t' 

if [[ $# -ne 1 ]] ; then echo "Requires one argument: the file to process" ; exit 1 ; fi 

FILENAME="$1" 

RELEVANT=$(sed -n '/^==*$/,/^==*$/p' "$FILENAME" | sed '1d' | head -n '-1') 
CDR_PKEY=$(echo "$RELEVANT" | \ 
    grep '$insert_vars\['"'cdr_pkey'\]" | \ 
    sed 's/.*=\(.*\)/\1/') 
echo "$RELEVANT" | sed '1,2d' | \ 
    sed "s/.*/${CDR_PKEY}$WHAT_DID_YOU_MEAN_BY_TAB\0/" 

以下find命令是一個示例使用,但你的情況將取決於你的日誌是如何組織的。

find . LOG_PATTERN -exec THIS_SCRIPT '{}' \;

最後,我忽略了把CSV頭的輸出的問題。這很容易在帶外完成。

(編輯:更新腳本來反映意見的討論)

+0

優秀!我只需要把'$ id \ t $ g1 \ t ...'一次,,所以我把。根據您的腳本,我已經添加了我自己的答案。萬分感謝 ! – Sudhi

+0

如果我理解你的編輯正確,你也可以將'RELEVANT'行從'... sed'1d'...'改爲'... sed 1,2d ...'。 –

+0

如果我這樣做(並刪除'grep -v'id'')我沒有得到第一個'cdr_pkey'值。它只是從第二列'id'值 – Sudhi

1

編輯:詹姆斯告訴我,去年echo改變sed... 1d ...... 1,2 ...和丟棄grep -v 'id'應該做的伎倆。
確認它有效。所以改變下面。再次感謝James Wilcox。


基於@James腳本,這是我想出的。我只是管道的最後迴音 grep -v 'id'
再次感謝詹姆斯·威爾考克斯

WHAT_DID_YOU_MEAN_BY_TAB='\t' 

if [[ $# -lt 1 ]] ; then echo "Requires at least one argument: the files to process" ; exit 1 ; fi 

echo -e "key\tid\tg1\ti1\td1\tc1\tr1\tg2\ti2\td2\tc2\tr2\tg3\ti3\td3\tc3\tr3" 

for i in "[email protected]" 
do 
    FILENAME="$i" 
    RELEVANT=$(sed -n '/^==*$/,/^==*$/p' "$FILENAME" | sed '1d' | head -n '-1') 
    CDR_PKEY=$(echo "$RELEVANT" | \ 
     grep '$insert_vars\['"'cdr_pkey'\]" | \ 
     sed 's/.*=\(.*\)/\1/') 
    echo "$RELEVANT" | sed '1, 2d' | \ 
     sed "s/.*/${CDR_PKEY}$WHAT_DID_YOU_MEAN_BY_TAB\0/" 
    #the one with grep looked like :- 
    #echo "$RELEVANT" | sed '1d' | \ 
     #sed "s/.*/${CDR_PKEY}$WHAT_DID_YOU_MEAN_BY_TAB\0/" | grep -v 'id' 
done