grep IP addresses in expect script

5,199

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 makes grep 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 ..

Share:
5,199

Related videos on Youtube

user3319356
Author by

user3319356

Updated on September 18, 2022

Comments

  • user3319356
    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
      terdon about 10 years
      Please show us your input as well. Are we talking IPv4 or 6?
    • user3319356
      user3319356 about 10 years
      ipv4, 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
      terdon about 10 years
      No, 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
      user3319356 about 10 years
      aha, 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
      cuonglm about 10 years
      Maybe you forget to escape the first curly brace.
    • terdon
      terdon about 10 years
      That'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
      terdon about 10 years
      Right, I thought you wanted to save the ip in a variable which is why I used ip=$(), you probably don't want that. Try send -- "/usr/xpg4/bin/grep -Po 'ip_v4=\"\K[0-9.]+' $filename". Also, why are you expecting an email address as a reply?
    • user3319356
      user3319356 about 10 years
      it'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
      Angel Todorov about 10 years
      brackets 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
    user3319356 about 10 years
    well 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
    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 was send -- "ip=$(/usr/xpg4/bin/grep -Po 'ip_v4="\K[0-9.]+' $filename) \r", you probably also need to escape the ", try send -- "ip=$(/usr/xpg4/bin/grep -Po 'ip_v4=\"\K[0-9.]+' $filename)"
  • user3319356
    user3319356 about 10 years
    this is the #!/usr/local/bin/expect , shouldn't the variable be se as set VAR [something]?
  • terdon
    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
    user3319356 about 10 years
    yes, still is not working, but thanks for help...This expect is killing me also
  • terdon
    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
    user3319356 about 10 years
    I updated the question
  • terdon
    terdon about 10 years
    @user3319356 yes, did you see my comment? You probably don't want ip=$().
  • Jeff Hewitt
    Jeff Hewitt about 10 years
    This 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.