Badmanchild
Badmanchild

Reputation: 1020

How can I use Expect to inline parse a line into multiple variables?

I'm trying to parse a single line of text that looks like this:

Blah blah A=1234 B=5678 C=9999 blah blah

I want to populate three vars, A B and C, with the values from that line.

Ideally I would like to use an expect script that looks something like this pseudocode:

file.exp:

expect {
    "*A=" $A " B=" $B " C=" $C " *\r\n"
}

Obviously this will not run, but you can see what I'm trying to do. I know I could do something like the code below, but it's a lot of typing and not as readable:

expect {
    * {
        set line split $expect_out(buffer) " "
        set A lindex (split (lindex $line 3) "=") 1
        set B lindex (split (lindex $line 4) "=") 1
        set C lindex (split (lindex $line 5) "=") 1
    }
}

Any ideas?

Upvotes: 1

Views: 3645

Answers (3)

glenn jackman
glenn jackman

Reputation: 247240

If you don't know what your variables names are called, then this is very generic:

expect {
    -re {(\w+)=(\S+)} {
        lappend variables $expect_out(1,string)
        set $expect_out(1,string) $expect_out(2,string)
        exp_continue
    }
    eof
}
foreach varname $variables {puts "$varname=[set $varname]"}

You should alter the eof condition as appropriate -- that expect block will fall into an infinite-ish loop (depending on your timeout value) without an appropriate exit condition.

Also, my regular expression won't work for values with whitespace, e.g. X="a string". Obviously this depends on what you expect to encounter.

Upvotes: 4

Badmanchild
Badmanchild

Reputation: 1020

Tcl's "scan" command works just like sscanf:

expect * {
    scan $expect_out(buffer) "A=%i B=%i C=%i" A B C
}

Upvotes: 1

Hai Vu
Hai Vu

Reputation: 40803

Here is one way to do it:

expect -re {^.*A=(\d+)\s+B=(\d+)\s+C=(\d+).*$} {
    set A $expect_out(1,string)
    set B $expect_out(2,string)
    set C $expect_out(3,string)
    # Do something with $a, $b, and $c
}

The -re flag tells expect to use regular expression, and parse the result into $expect_out(1,string), ...

Upvotes: 3

Related Questions