我正在尝试创建一个脚本来解析日志文件,并找到每行特定部分的重复匹配,如果存在重复,我需要在第一行执行与重复匹配的脚本。我的日志详细信息是:
#: 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并生成要执行的脚本。
一次性解决方案。它利用了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 ' '
以下是使用GNU awk
:的一种方法
awk '$NF in array && !dup[$NF] { print array[$NF]; dup[$NF]++ } { array[$NF]=$2 }' file.txt
结果:
178
一种方法:
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
,只打印第一行。grep
命令的-n
标志打印匹配的实际行号,如果不需要,可以将其删除。
要生成正则表达式,我们有4个命令。
sed -ne '/^#/s/.*SIP/([0-9]*)$/1/p' log.txt
将仅提取以#
开头的行上存在的SIP号码- sed(数字列表)的输出然后通过管道进行数字排序
- 排序后,我们可以使用
uniq -d
命令只打印重复的行 - 最后,我们用
paste
命令将所有数字连接在一行中,我们使用-d '|'
选项指定要用'|'分隔的数字,'|'是OR的正则表达式运算符
因此,正则表达式将查找具有任何一个重复数字的行。
希望这有帮助=)
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]
}
}