簡體   English   中英

使用 sed/awk 和正則表達式處理日志

[英]Using sed/awk and regex to process logs

我有 1000 個由非常冗長的 PHP 腳本生成的日志文件。 大體結構如下

###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 ,每個都有自己的一組$g1,$i1,$rating1...
測試該格式后,excel可以讀取。 現在我只想將它擴展到所有這 1000 個文件。
我只是不確定如何進一步進行。 下一步是什么?

以下 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 標頭放在 output 上的問題。 這很容易在帶外完成。

(編輯:更新腳本以反映評論中的討論。)

編輯:詹姆斯告訴我,將最后一個echo中的sed... 1d...更改為... 1,2...並刪除grep -v 'id'應該可以解決問題。
確認它有效。 所以下面改一下。 再次感謝詹姆斯威爾科克斯。


基於@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 "$@" 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM