2012-10-05 58 views
2

我想創建一個腳本來分析日誌文件,找到每一行的特定部分的重複匹配,如果存在重複我需要在第一線執行一個腳本匹配重複。我的日誌細節:查找重複並在比賽中執行腳本

#: 177   101 User 1 Channel: SIP/101 
#: 178   117 User 2 Channel: SIP/117 
#: 179   150 User 3 Channel: SIP/150 
#: 356   166 User 4 Channel: SIP/166 
#: 387   117 User 2 Channel: SIP/117 

我想找到根據日誌文件的SIP /部分重複,但我將需要執行基於日誌文件的一部分#腳本。基於這個日誌,我需要執行#:178行的腳本。

到目前爲止,我已經使用

egrep -o ".{50}SIP.{4}"

找到基於行的SIP /部分重複。我不清楚我怎樣才能讓整個系列獲得#:178並生成腳本來執行。要做到這一點

回答

0

方式一:

grep -nE "$(sed -ne '/^#/s/.*SIP\/\([0-9]*\)$/\1/p' log.txt | sort -n | uniq -d | paste -sd '|')" log.txt | head -n 1 

這將打印(根據您的示例文件):

2:#: 178   117 User 2 Channel: SIP/117 

主要命令是grep -nE "$(...)" log.txt,它會搜索你的日誌文件中反覆行和打印它們(正則表達式是動態生成的,我將在下面解釋它)。然後輸出到head -n 1以僅打印第一行。該-n標誌的grep命令打印的比賽中真正的行號,你可以,如果你不需要是刪除它。

爲了生成正則表達式,我們有4個指令。

  1. sed -ne '/^#/s/.*SIP\/\([0-9]*\)$/\1/p' log.txt將只提取出現在以#開頭的行上的SIP號碼。
  2. sed(數字列表)的輸出然後通過管道進行數字排序
  3. 對其進行排序後,我們可以使用uniq -d命令僅打印重複行。
  4. 最後,我們用paste命令將所有數字連接在一起,使用-d '|'選項來指定我們希望用'|'分隔的數字,它是OR的正則表達式運算符。

因此,正則表達式將找到具有任何一個重複數字的行。

希望這有助於=)

+0

當我運行你的命令時,它返回'#:177 101 User 1 Channel:SIP/101'。 – Annjawn

+0

你是如何運行它的?你是否用OP的例子的確切副本創建了一個'log.txt'文件?我覺得奇怪的是,從行首開始缺少原始行號= S –

+0

是的,log.txt與OP的日誌文件完全相同。 – Annjawn

1

下面是使用GNU awk一個辦法:

awk '$NF in array && !dup[$NF] { print array[$NF]; dup[$NF]++ } { array[$NF]=$2 }' file.txt 

結果:

178 
+0

您應該可以在一次傳遞中執行此操作 - 在每條記錄上檢查相應的數組條目是否存在並在設置數組值之前將其打印並添加第二個數組,用於跟蹤是否已打印條目(以避免在第三次及以後的事件中再次打印)。 – twalberg

+0

@twalberg:非常好的建議,謝謝! – Steve

1

一次通過的解決方案。它採用的uniq優勢支持跳過字段和重複只有標誌

sed -n '/SIP/{s/^#:\s\+\([0-9]\+\).*SIP\/\([0-9]\+\)/\1 \2/;p}' file.txt | sort -k2,2 -n | uniq -f 1 -d | cut -f1 -d ' ' 
+0

好主意=)我可能會建議添加'-n'標誌進行排序嗎? –

+0

@JanitoVaqueiroFerreiraFilho,趕上。完成 – iruvar

+0

另一個小建議:也許在sed的substitute命令中使用'p'標誌並使用'-n'命令行選項?這是概括並忽略不符合模式的行。 –

0

AWK很適合這種事情。

這是一個可讀的單程解決方案。

#!/usr/bin/env awk -f 

{ 
    sip = $3 
    script = $2 

    count[sip]++ 

    if (count[sip] == 1) { 
     scripts[sip] = script 
    } 
    else if (count[sip] > 1) { 
     to_run[sip] = scripts[sip] 
    } 
} 

END { 
    for (sip in to_run) { 
     print to_run[sip] 
    } 
}