grep IP addresses in expect script
Your main problem is this line
cat $filename | grep {1,3\}\.\{1,3\}\.\{1,3\}\.\{1,3\} \r"
Apart from the useless use of cat, the main mistake is that {1,3}
means "match 1,2 or 3" times, but your not telling it what to match. The syntax is also wrong, {}
need to be escaped for regular grep
. What you are looking is better written as:
grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' filename
This uses PCRE syntax (-P
) where \d
means "digits" and which I find easier but to use standard grep
regular expressions (BREs) you could do:
grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
The
-o
makesgrep
print only the matching part of the line.You never want to match the end of line character, there's no need. You should always try and make your regular expressions as simple as possible. It is always best to use the smallest, simplest expression that matches your data.
You most certainly don't want to search for
\r
. While Windows does end lines with\r\n
, most systems don't and in any case, there's little point in looking for it. If you need to match to the end of a line, use$
which will work in all cases.
Anyway, to save in a variable do this:
ip=$(grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' filename)
You can now echo $ip
to print the IP.
Based on your last edit, I am assuming that you want the ip defined by the ipAddress tag. I will now give you the obligatory warning: NEVER use regular expressions to parse XML or similar formats. That said, to get only the ipAddress IP, do this:
ip=$(grep -Po 'ip_v4="\K[0-9.]+' $filename)
The \K
discards whatever was matched before it so you get only the IP part and since you know that the IP you are looking for is always preceded by ip_v4="
, you can simply look for the longest string that contains only numbers and .
.
Related videos on Youtube
user3319356
Updated on September 18, 2022Comments
-
user3319356 over 1 year
This is part of code in an expect script, I have a problem with searching IP addresses from a file whose name is in the variable
$filename
.#!/usr/local/bin/expect -- ###Made by Etihkru#### set env(TERM) vt100 set env(SHELL) /bin/sh set env(HOME) /usr/local/bin exp_internal 1 set PASSWORD eri set SIU [lindex $argv 0] match_max 1000 if {$SIU == ""} { puts "Missing name of SIU. Run command as perl SIUADD FRTXXX" exit } spawn ssh mashost set USER admin set PASS hidden expect { "assword" {send "$PASSWORD\r"} } expect "ranosusr@rn2osscs603" send -- "cd /var/opt/ericsson/edd/ARNE_SIU \r" expect "ranosusr@rn2osscs603" send -- "grep -il $SIU *\r" set prompt {ranosusr@rn2osscs603> } expect -re "(FXL\\S+\\.xml).*$prompt$" set filename $expect_out(1,string) send -- "cat $filename | grep 'url=' \r" expect -re "something.*$prompt$" //Expect this ip adreess ??? set IP $expect_out(1,string)//put it to variable IP ??? spawn ssh admin@$ip expect { -re "RSA key fingerprint" {send "yes\r"} timeout {puts "Host is known"} } expect { "assword" {send "$PASS\r"} } expect "Osmon>" send -- "resumePMMeasurements STN=0,MeasurementDefinition=0 sftp://pmup-rn2sossv605:[email protected]/GRAN/rn2sossv605/$SIU/NeTransientUp \r" expect "Osmon>" send -- "getalarmlist \r" expect -re "(\Operation Succeed\)" send -- "rev \r" expect "Osmon>" send -- "subscribe 10.211.149.40 1 \r" expect "Osmon>" send -- "getsubscriptionstatus 1 \r" expect "Osmon>" interact
This is the ouput:
expect: does "> cat FXL704_FRTAMX_SIU_ARNE.xml | grep 'url=' " (spawn_id exp4) match glob pattern "ranosusr@rn2osscs603"? no expect: does "> cat FXL704_FRTAMX_SIU_ARNE.xml | grep 'url=' \r\r\n" (spawn_id exp4) match glob pattern "ranosusr@rn2osscs603"? no <emUrl url="10.80.31.123"/> expect: does "> cat FXL704_FRTAMX_SIU_ARNE.xml | grep 'url=' \r\r\n <emUrl url="10.80.31.123"/>\r\r\n" (spawn_id exp4) match glob pattern "ranosusr@rn2osscs603"? no ranosusr@rn2osscs603> expect: does "> cat FXL704_FRTAMX_SIU_ARNE.xml | grep 'url=' \r\r\n <emUrl url="10.80.31.123"/>\r\r\nranosusr@rn2osscs603> " (spawn_id exp4) match glob pattern "ranosusr@rn2osscs603"? yes
I need the pure IP address, cleared from other characters (e.g.
10.80.31.123
), because I need to use it in next SSH login, so I need to assign it to a variable$IP
.-
terdon about 10 yearsPlease show us your input as well. Are we talking IPv4 or 6?
-
user3319356 about 10 yearsipv4, what do you mean on input, when I connect to server it looks like the second line above, if this is what you meant?
-
terdon about 10 yearsNo, you are trying to grep an IP within a file. It would help to know what the rest of the line looks like. Is the IP on its own line? Surrounded by text? Other numbers? What kind of data could we expect to see in $filename?
-
user3319356 about 10 yearsaha, ok, so the ipaddress is in xml. file <connectionStatus string="ON"/> <Connectivity> <DEFAULT> <emUrl url="10.82.30.212"/> <ipAddress ip_v4="10.82.30.212"/> <hostname string=""/> <nodeSecurityState state="ON"/> <boardId string=""/> <Protocol number="0"> ..........there are two address, they are the same, and I need to grep one of them:)
-
cuonglm about 10 yearsMaybe you forget to escape the first curly brace.
-
terdon about 10 yearsThat's why you should always post your input. Please edit your question and add that. So, which of the 2 IPs you are showing should be matched?
-
terdon about 10 yearsRight, I thought you wanted to save the ip in a variable which is why I used
ip=$()
, you probably don't want that. Trysend -- "/usr/xpg4/bin/grep -Po 'ip_v4=\"\K[0-9.]+' $filename"
. Also, why are you expecting an email address as a reply? -
user3319356 about 10 yearsit's not email address, this is the prompt of server....Still getting error invalid command name "0-9." while executing "0-9." invoked from within "send -- "/usr/xpg4/bin/grep -Po 'ip_v4=\"\K[0-9.]+' $filename""
-
Angel Todorov about 10 yearsbrackets are special to Tcl (like backticks for the shell), so they need to be escaped:
send -- "/usr/xpg4/bin/grep -Po 'ip_v4=\"\\K\[0-9.\]+' $filename\r"
-
-
user3319356 about 10 yearswell it's not working, when I use ip=$(grep -Po 'ip_v4="\K[0-9.]+' $filename) I got ite to file. Writing to stdout instead.\r\nThe file '-import' can not be found.\r\nranosusr@rn2osscs603" invalid command name "0-9." while executing "0-9." invoked from within "send -- "ip=$(/usr/xpg4/bin/grep -Po 'ip_v4="\K[0-9.]+' $filename) \r"" (file "siu1" line 37)
-
terdon about 10 years@user3319356 Why are you sending the
\r
? That does not end a line, you need\n
(*nix) or\r\n
(Windows). When typing commands, please use backticks (``` ` ``) to format them. If your command wassend -- "ip=$(/usr/xpg4/bin/grep -Po 'ip_v4="\K[0-9.]+' $filename) \r"
, you probably also need to escape the"
, trysend -- "ip=$(/usr/xpg4/bin/grep -Po 'ip_v4=\"\K[0-9.]+' $filename)"
-
user3319356 about 10 yearsthis is the #!/usr/local/bin/expect , shouldn't the variable be se as set VAR [something]?
-
terdon about 10 years@user3319356 sorry, I'm not really familiar with
expect
syntax, I can only help you with getting the shell command right. -
user3319356 about 10 yearsyes, still is not working, but thanks for help...This expect is killing me also
-
terdon about 10 years@user3319356 update your question with the exact
expect
script you're using. The regular expression you had posted is wrong and my answer corrects that. Show us how you're using it and we might be able to help more. -
user3319356 about 10 yearsI updated the question
-
terdon about 10 years@user3319356 yes, did you see my comment? You probably don't want
ip=$()
. -
Jeff Hewitt about 10 yearsThis regex should work too:
(\d{1,3}\.){3}\d{1,3}
. You should also note that an accurate regex to extract IPs is far more monstrous.