您可以使用regexp
在expect
本身直接使用-re
標誌。感謝Donal指出單引號和雙引號問題。我已經用兩種方法給出瞭解決方案。
我已經創建了內容的文件,如下所示,
Id Name
-------------------
abcd 12 John Smith
這不過是你的java程序的控制檯輸出。我已經在我的系統中對此進行了測試。即我只是用cat
來模擬你的程序輸出。您只需使用程序命令替換cat
代碼即可。簡單。 :)
雙引號:
#!/bin/bash
expect -c "
spawn ssh [email protected]
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 [email protected]
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)
等等。
正如多納爾指出的那樣,最好使用單引號的方法,因爲它看起來不太凌亂。 :)
如果是雙引號,則不需要用反斜槓來轉義\r
。
更新:
我從-\r\n(\w+\s+\w+)\s\s
改變regexp
到-\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
和模式flow
匹配的字符串文本flow
。
現在,爲了防止.*
僅匹配字符串flow
的第一個匹配項,我們將?
添加到它。這將有助於該模式表現爲非貪婪的態度。
現在,再來回到你的問題。如果我們使用.*\s\s
,那麼它將整條生產線,因爲它正試圖儘可能地匹配匹配。這是正則表達式的共同行爲。
更新版本3:
在下列方式你的代碼。
x=$(expect -c "
spawn ssh [email protected]
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
命令。
問題的核心在於你試圖將期望腳本放入雙引號的shell文本中。這會迫使你使用_Lots_的反斜槓引用。雖然您可以這樣做,但將期望腳本放在自己的文件中(例如'mydostuff.exp')會使一切變得簡單。然後你可以用'expect mydostuff.exp'運行它... – 2014-11-23 23:21:47