【问题标题】:Need help extracting specific lines from a changing logfile using expect需要帮助使用期望从更改的日志文件中提取特定行
【发布时间】:2019-08-12 23:11:33
【问题描述】:

我正在尝试使用 expect 脚本通过 telnet 访问远程设备,在本地读取/保存远程“EVENTLOG”,然后从日志文件中提取特定行(序列号)。问题是日志文件不断变化,所以我需要一种搜索​​特定字符串的方法。远程设备是基于 Linux 的,但没有 grep、vi、less 等,因为它是 QNX Neutrino,因此必须在本地进行。

我已经成功地获得了 telnet,读取文件并在本地保存在控制之下,但是当我开始“读取”文件时,我遇到了问题。目前我只是想让它打印它找到的内容,但脚本只是退出,除了一些额外的大括号之外没有报告任何内容??

#!/usr/bin/expect -f

set timeout -1
    log_user 1

    spawn telnet $IP
    match_max 100000
    expect "login:"
    send -- "$USER\r"
    expect "Password:"
    send -- "$PW\r"
    expect "# "
    send -- "\r"

#at this point logged into device
#send command to generate the "dallaslog"

    set dallaslog [open dallaslog.txt w]
    expect "#" 
        send -- "cat `ls -rt /LOG/event*`\r"

    expect "(cat) exited status=0"
    set logout $expect_out(buffer)
    puts $dallaslog "$logout"
    close $dallaslog
    unset expect_out(buffer)

    set dallasread [open dallaslog.txt r]
    set lines [split [read $dallasread] "\r"]
    close $dallasread

    puts "${green}$lines{$normal}"
#a debug line to print $dallasread in green so I can verify it works up to here

    foreach line $lines {
        if {[regexp {.*Dallas ID: 0.*\n} $lines match]} {
        if {$match == 1} {
            puts $line  ;# Prints whole line which has 1 at end 
        }
        }
    }
    expect "# "
    send -- "exit\r"
    interact

我(最终)要寻找的是捕获以“Dallas ID:”开头的任何行然后将该信息保存到变量中的脚本,因此我可以使用“scan”命令来解析该行并提取信息。

我得到的是:

(the results from $lines being "puts" in green)
"...
<ENTRY TIME="01/01/1970 00:48:07" PROC="syncd" FILE="mips.cc" LINE="208" NUM="10000">
UTC step from 01/01/1970 00:48:08 to 01/01/1970 00:48:07
</ENTRY>

Process 3174431 (cat) exited status=0
}{}
# exit

Process 3162142 (sh) exited status=0.
Connection closed by foreign host."

提前感谢您的所有帮助。我是 TCL/expect 的新手(自去年​​ 7 月以来一直在玩弄它),但我发现它是一个非常强大的工具,但我很难调试!

编辑:根据@meuh 的回复添加了更多信息。 示例:达拉斯 ID 最多可以有 4 个,但一般我只有 0 和 1。目标是将到达达拉斯 ID 的 SN、BC、CN 保存为变量以放入单独的文本文件中。

<ENTRY TIME="01/01/1970 00:00:06" PROC="sys" FILE="PlatformUtils.cpp" LINE="1227" NUM="10044">
Dallas ID: 1 SN:00000622393A BC: J4AD945 CN: IS200BPPBH2BMD R0: 001C 
</ENTRY>

我使用的 foreach 循环是一个关于堆栈溢出的旧问题的示例,我尝试修改以在此处使用,但未成功。

编辑:我还应该提到,这个事件日志每次被读取时大约有 800 行长,这就是为什么我没有发布它的摘录。

【问题讨论】:

  • 您可能希望使用log_file dallaslog.txt expect 命令,而不是手动捕获输出并写入文件
  • @glennjackman 我尝试了你的建议,使用命令 log_file -noappend dallaslog.txt 但脚本似乎无法打开 dallaslog.txt 文件,因为我的 puts $lines 命令不再有输出
  • 您可以在cat 命令完成后关闭日志记录:使用不带参数的log_file
  • 一个有趣的发现:如果我使用log_file 命令然后设置log_user 0 来隐藏控制台输出,那么日志中的变量就会变得未定义。但是,如果我手动捕获输出(即使禁用了控制台输出),它也一切正常。除非我使用-a 命令!太棒了!

标签: tcl expect


【解决方案1】:

这个正则表达式行可能没有做你想做的事:

if {[regexp {.*Dallas ID: 0.*\n} $lines match]} {
    if {$match == 1} {
        puts $line  

您正在传递列表$lines,而不是大概是单行$line。变量match 将设置为匹配的字符串,因此必须包含单词“Dallas”等,因此它永远不会为 1。 您的代码注释说打印以 1 结尾的整行,但我不确定您在寻找什么,因为您没有任何适合正则表达式的示例数据。

如果您选择使用分组的正则表达式模式,您可以捕获部分行,因此可能不需要进一步的scan。比如

regexp {PROC="([a-z]*)"} $line match submatch

在上面的示例中将变量子匹配设置为syncd


您可能还会遇到一个基本问题,这是由 tcl 处理来自文件的输入的\r\n 引起的。您从 $expect_out(buffer) 得到的行确实有 2 个字符作为行尾分隔符。然而, 当使用read 时,我相信默认情况下,它会将相同的序列转换为规范化的\n。所以你的分裂不会做任何事情,你需要分裂\n而不是\r。您可以检查您拥有的行列表的大小

puts [llength $lines]

如果它是 1,那么你的拆分不起作用。替换为

set lines [split [read $dallasread] "\n"]

这应该有助于你的循环,例如你可以尝试

foreach line $lines {
    if {[regexp {.*Dallas ID: (\d+) SN:([^ ]+)} $line match idnum SN]} {
        puts $line
        puts "$idnum, $SN"
    }
}    

您必须删除正则表达式末尾的\n,因为拆分后它不再存在。我用(\d+) 扩展了正则表达式示例以匹配id 号(\d 匹配一个数字),([^ ]+) 以匹配文本SN: 之后的任意数量的非空格字符。

这些值是使用() 分组捕获的,并放在变量 idnum 和 SN 中,您应该可以通过第二个puts 命令看到输出。

【讨论】:

  • 也许我的正则表达式不太正确!当我使用您的示例时,我实际上得到sys 作为结果,因为它在第一次迭代时停止。如果我使用-all 操作数,那么我会得到syncd,因为它只给出最后一个匹配项。如果我尝试使用我的正则表达式,我仍然没有输出。也许我的编辑会对这种情况有所了解!
  • 我在答案中添加了第二部分。您需要检查您的 split 是否实际上给了您一个列表,而不仅仅是一个很长的字符串。这将破坏您以后解析每一行的尝试。我已经给出了一个较长的正则表达式示例,您可以使用它。
  • 这很完美!我曾多次玩弄\r\n 并采取了更近/更远的步骤,但是您解释它的方式很有帮助!不仅如此,你的正则表达式让我看到我做错了什么;将正则表达式视为“简单搜索”工具,而不是发挥其更多潜力!
猜你喜欢
  • 2016-07-05
  • 2022-08-02
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 2020-02-13
  • 2018-04-06
  • 1970-01-01
相关资源
最近更新 更多