在匹配项上找到重复和执行脚本

时间:2012-10-05 21:17:42

标签: perl bash grep

我正在尝试创建一个脚本来解析日志文件并查找每行特定部分的重复匹配,如果存在重复,我需要在匹配重复的第一行执行脚本。我的日志详细信息是:

#: 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并生成要执行的脚本。

4 个答案:

答案 0 :(得分:1)

这是使用GNU awk的一种方式:

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

结果:

178

答案 1 :(得分: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 ' '

答案 2 :(得分: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 '|'选项指定我们希望数字用' |&#39分隔; s,它是OR的正则表达式运算符。
  5. 因此,正则表达式将找到具有任何一个重复数字的行。

    希望这有助于=)

答案 3 :(得分: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]
    }
}