您可以使用regexp
in expect
本身直接使用-re
旗帜。感谢 Donal 指出单引号和双引号问题。我已经给出了使用两种方式的解决方案。
我创建了一个文件,内容如下,
Id Name
-------------------
abcd 12 John Smith
这只不过是 java 程序的控制台输出。我已经在我的系统中对此进行了测试。即我刚刚模拟了你的程序的输出cat
。您只需更换cat
使用您的程序命令进行编码。简单的。 :)
双引号 :
#!/bin/bash
expect -c "
spawn ssh user@domain
expect \"password\"
send \"mypassword\r\"
expect {\\\$} { puts matched_literal_dollar_sign}
send \"cat input_file\r\"; # Replace this code with your java program commands
expect -re {-\r\n(.*?)\s\s}
set output \$expect_out(1,string)
#puts \$expect_out(1,string)
puts \"Result : \$output\"
"
单引号:
#!/bin/bash
expect -c '
spawn ssh user@domain
expect "password"
send "mypasswordhere\r"
expect "\\\$" { puts matched_literal_dollar_sign}
send "cat input_file\r"; # Replace this code with your java program commands
expect -re {-\r\n(.*?)\s\s}
set output $expect_out(1,string)
#puts $expect_out(1,string)
puts "Result : $output"
'
正如你所看到的,我已经使用了{-\r\n(.*?)\s\s}
。这里的大括号防止任何变量替换。在您的输出中,我们有一个充满连字符的第二行。然后换行。然后是你的第三行内容。让我们解码所使用的正则表达式。
-\r\n
是将一个连字符和一个新行匹配在一起。这将匹配第二行中的最后一个连字符和换行符,而换行符现在又进入第三行。所以,.*?
将匹配所需的输出(即 abcd 12),直到遇到与以下内容匹配的双空格\s\s
.
您可能想知道为什么我需要用于获取子匹配模式的括号。
一般来说,expect
将保存期望的整个匹配字符串expect_out(0,string)
并将所有匹配/不匹配的输入缓冲到expect_out(buffer)
。每个子匹配将保存在字符串的后续编号中,例如expect_out(1,string)
, expect_out(2,string)
等等。
正如 Donal 指出的,最好使用单引号的方法,因为它看起来不那么混乱。 :)
不需要逃避\r
如果有双引号,则使用反斜杠。
Update :
我已经改变了regexp
from -\r\n(\w+\s+\w+)\s\s
to -\r\n(.*?)\s\s
.
通过这种方式 - 您的要求 - 例如match any number of letters and single spaces until you encounter first occurrence of double spaces in the output
现在,让我们来回答你的问题。你提到你已经尝试过-\r\n(\w+)\s\s
。但是,这里有一个问题\w+
。记住\w+
不会匹配空格字符。您的输出中有一些空格,直到双空格。
正则表达式的使用取决于您对要匹配的输入字符串的要求。您可以根据需要自定义正则表达式。
更新版本2:
有什么意义.*?
。如果你单独问,我会重复你的评论。在正则表达式中,*
是一个贪心运算符并且?
是我们的救星。让我们将字符串视为
Stackoverflow is already overflowing with number of users.
现在看看正则表达式的效果.*flow
如下。
*
匹配任意数量的字符。更准确地说,它匹配尽可能长的字符串,同时仍然允许模式本身匹配。所以,由于这个原因,.*
在模式中匹配字符Stackoverflow is already over
and flow
模式与文本匹配flow
在字符串中。
现在,为了防止.*
仅匹配字符串第一次出现的位置flow
,我们正在添加?
到它。它将帮助模式表现得非贪婪的方式。
现在,再次回到你的问题。如果我们已经使用过.*\s\s
,那么它将匹配整行,因为它试图尽可能匹配。这是正则表达式的常见行为。
更新版本3:
按以下方式获取代码。
x=$(expect -c "
spawn ssh user@host
expect \"password\"
send \"password\r\"
expect {\\\$} { puts matched_literal_dollar_sign}
send \"cat input\r\"
expect -re {-\r\n(.*?)\s\s}
if {![info exists expect_out(1,string)]} {
puts \"Match did not happen :(\"
exit 1
}
set output \$expect_out(1,string)
#puts \$expect_out(1,string)
puts \"Result : \$output\"
")
y=$?
# $x now contains the output from the 'expect' command, and $y contains the
# exit status
echo $x
echo $y;
如果流程正确,则退出代码的值为 0。否则,它将为 1。通过这种方式,您可以检查 bash 脚本中的返回值。
看一下here了解有关info exists
命令。