Perl 查找副本并在匹配项上执行脚本

Perl 查找副本并在匹配项上执行脚本,perl,bash,grep,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/1

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

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

一种方法:

grep -nE "$(sed -ne '/^#/s/.*SIP\/\([0-9]*\)$/\1/p' log.txt | sort -n | uniq -d | paste -sd '|')"  log.txt | head -n 1
这将打印(基于您的示例文件):

主命令是
grep-nE“$(…)”log.txt
,它将在日志文件中搜索重复的行并打印它们(该行的正则表达式是动态生成的,我将在下面解释)。然后,输出通过管道传输到
头-n1
以仅打印第一行。
grep
命令的
-n
标志打印匹配的实际行号,如果不需要,可以将其删除

要生成正则表达式,我们有4个命令

  • sed-ne'/^#/s/*SIP\/\([0-9]*\)$/\1/p'log.txt
    将仅提取以
    开头的行上的SIP编号
  • sed(数字列表)的输出然后通过管道进行数字排序
  • 排序后,我们可以使用
    uniq-d
    命令仅打印重复行
  • 最后,我们使用
    paste
    命令将所有数字连接在一行中,我们使用
    -d'|'
    选项指定我们希望数字以'|'分隔,这是OR的正则表达式运算符
  • 因此,正则表达式将查找具有任何一个重复编号的行


    希望这有帮助=)

    这里有一种使用GNU awk的方法:

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

    178
    

    一次性解决方案。它利用了
    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 ' '
    

    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]
        }
    }
    

    当我运行您的命令时,它返回
    #:177 101 User 1 Channel:SIP/101
    。您是如何运行它的?您是否创建了一个带有OP示例精确副本的
    log.txt
    文件?我觉得奇怪的是,从line=SYes的开头就缺少了原始行号log.txt与OP的日志文件完全相同。您应该能够一次完成此操作-在每个记录上,检查是否存在相应的数组项,并在设置数组值之前打印它,并添加第二个数组,用于跟踪条目是否已打印(以避免在第三次和后续出现时再次打印).Good idea=)我可以建议添加
    -n
    标志进行排序吗?另一个小建议:可能在sed的替换命令中使用
    p
    标志,并使用
    -n
    命令行选项?这是泛化并忽略与模式不匹配的行。
    #!/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]
        }
    }