[英]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'
應該可以解決問題。
確認它有效。 所以下面改一下。 再次感謝詹姆斯威爾科克斯。
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.