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

4

4 回答 4

1

这是一种使用方法GNU awk

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

结果:

178
于 2012-10-05T21:32:18.370 回答
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 ' '
于 2012-10-05T21:47:56.140 回答
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 的正则表达式运算符。

因此,正则表达式将查找具有任何一个重复数字的行。

希望这会有所帮助=)

于 2012-10-05T21:31:24.440 回答
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]
    }
}
于 2012-10-05T21:59:50.030 回答