Expect / tcl:如何检查屏幕上打印的列表的每个元素是否在用户定义的列表中?

问题描述 投票:1回答:1

嗨潜在的救生员,

我正在处理一个bash程序,它会将行打印到命令行中,例如:

Which LYSINE type do you want for residue 4
0. Not protonated (charge 0) (LYS)
1. Protonated (charge +1) (LYSH)

Type a number:0
Which LYSINE type do you want for residue 16
0. Not protonated (charge 0) (LYS)
1. Protonated (charge +1) (LYSH)

Type a number:0
Which LYSINE type do you want for residue 22
0. Not protonated (charge 0) (LYS)
1. Protonated (charge +1) (LYSH)

Type a number:0
Which LYSINE type do you want for residue 62
0. Not protonated (charge 0) (LYS)
1. Protonated (charge +1) (LYSH)

Type a number:0

在它说Type a number:的每个阶段,程序将等待用户输入,这将是数字0或1,如上所述(我在默认情况下键入了0)。

由于这些列表可能有几百长,我正在尝试编写一个expect脚本来自动执行此过程。以前我写过这样一个完成这项工作的脚本,但是非常手动并且让其他人使用起来很困惑:

#! /usr/bin/expect -f 
set timeout 2

# wanted lysine charges
set LYS_1 "4"
set LYS_2 "16"

set LYS "Which LYSINE type do you want for residue "

expect
  set timeout -1  
  spawn bash test.sh 
  expect {  
    #Lysine charge and default settings; 0 = non-protonated (0), 1 = protonated (+1)
    ${LYS}${LYS_1} {
      send "1\r"
      exp_continue
    }

    ${LYS}${LYS_2} {
      send "1\r"
      exp_continue
    }

    ${LYS} {
      send "0\r"
      exp_continue
    }

如果脚本遇到Which LYSINE type do you want for residue后跟416,它将输入1,或者如果未识别该数字,则默认输入0。这种格式存在多个问题:如果我想扩展LYS_X变量的数量,我需要将它们设置在顶部,并且还要添加其他集合

${LYS}${LYS_1} {
    send "1\r"
    exp_continue
}

进入底部。第二个问题是如果要求期望将残差4设置为1,它还会意外地将所有其他数字从4开始设置为1,例如1。 42,400,40006等

我试过用foreach循环来整理它:

#! /usr/bin/expect

set timeout 1

set LYS "Which LYSINE type do you want for residue "

expect
    set timeout -1
    spawn bash test.sh

    foreach q [list "4" "16"] {
        set LYS_q $q

        expect {
            ${LYS}${LYS_q} {
                send "1\r"
                exp_continue
            }

            ${LYS} {
                send "0\r"
                exp_continue
            }
        }
    }

哪里需要设置为“1”的残差数,可以包含在[list "4" "16"]中,但这似乎不起作用,只有列表中的第一个元素被设置,其他一切设置为0.然后test.sh脚本终止,然后LYS_q设置为第二个元素。当然,我不能在foreach循环中拥有spawn bash test.sh命令吗?

如果有人能就如何解决这个问题给我一些指导,我将非常感激。我是stackoverflow的新手,所以如果我错过了任何有用的信息,请不要犹豫!

提前致谢

bash tcl expect
1个回答
2
投票

我会使用正则表达式匹配:

set question {Which LYSINE type do you want for residue (\d+)}
set lysines {4 16}

spawn bash test.sh

expect  {
    -re $question {
        if {$expect_out(1,string) in $lysines} {
            send "1\r"
        } else {
            send "0\r"
        }
        exp_continue
    }
}

in运营商相对较新。如果您的期望没有,请使用

if {[lsearch -exact $lysines $expect_out(1,string)] != -1}

如果您的期望确实有in,您可以将上述内容缩短到此,因为返回的值将是布尔值1或0,您可以将其作为字符串发送。

expect  {
    -re $question {
        set response [expr {$expect_out(1,string) in $lysines}]
        send "$response\r"
        exp_continue
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.