我正在尝试创建一个脚本来解析日志文件并查找每行特定部分的重复匹配,如果存在重复,我需要在匹配重复的第一行执行脚本。我的日志详细信息是:
#: 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 :(得分: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个命令。
sed -ne '/^#/s/.*SIP\/\([0-9]*\)$/\1/p' log.txt
将仅提取以#
开头的行中出现的SIP号码。uniq -d
命令仅打印重复的行。paste
命令将所有数字加在一起,我们使用-d '|'
选项指定我们希望数字用' |&#39分隔; s,它是OR的正则表达式运算符。因此,正则表达式将找到具有任何一个重复数字的行。
希望这有助于=)
答案 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]
}
}