Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Regexp for space delimated line 1

Status
Not open for further replies.

NetworkGhost

IS-IT--Management
Apr 12, 2005
1,324
US
As I am new to regexp I promise I wont be asking remedial questions for too long. I would like to split a line into to 2 variables using regexp.

Line is:

hostname 192.168.0.1

Another poster help me with a different issue that worked great:

ex: regexp {.*(\(\d*/\d*\)).* = (\d*)/(\d*)/(\d*).*} $s a b

so I assign "hostname 192.168.0.1" to variable hostline I would like to parse that to 2 sep variables. Any help is appreciated


Free Firewall/Network/Systems Support-
 
In this case, split is even better than regexp. Since "space" is the default delimiter, you can either use:
set <listName> [split $hostline]
or, explicitly:
set <listName> [split $hostline " "]
where <listName> is the name of a list, say "list1"

then, lindex $<listName> 0 will yield "hostname", and lindex $<listName> 1 will yield "192.168.0.1"

_________________
Bob Rashkin
 
Of course, you can use regexp if you like:
regexp {([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})} $hostline a b
then $b will be 192.168.0.1

_________________
Bob Rashkin
 
Actuall, $a will also be the IP address, so you don't need b:
regexp {([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})} $hostline a

_________________
Bob Rashkin
 
I just realized you want both the hostname and the IP address. I still maintain that split and lindex are best suited to this case but regexp is way cool. The general syntax of the regular expression is:
stuff(what you want) etc.

In your case:
regexp {(.*)\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})} $hostline a b c

as follows:
(.*) any number of any characters. Since it's in parentheses, it's a group that will be saved to a variable when found.
\s a space. Not in parentheses so not saved
([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) 1 to 3 occurrences of a digit followed by a ".", four times (without the "." on the last). Parentheses again so it gets saved.
a the part of the string that matches the whole expression.
b the part of the string in the first parentheses (hostname)
c the part of the string in the second parentheses (IP address)

also, using special regexp shorthand:
regexp {(.*)\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})} $hostline a b c
says the same thing.

_________________
Bob Rashkin
 
Sweet. The explanation was awesome. I am still trying to figure out the other post. What about if this was in a list though? Should I make a lindex first? I will have several lines in a file. Kind of like a host file. I was thinking a foreach loop to go through the whole file. This is all for a SSH script I have. I appreciate you help.

Free Firewall/Network/Systems Support-
 
I think this is the simplest (though not, perhaps, the awesomest):
Code:
set fid [open <filename> r]
set linelist [split [read $fid] \n];#each line is an element in [i]linelist[/i]
close $fid
foreach line $linelist {
    #you don't even have to split if the only space is between [i]hostname[/i] and [i]IPadd[/i]
    set hostname [lindex $line 0]
    set IPadd [lindex $line 1]
    #...do what you will...
}

Now, I don't know what your ultimate goal is here but if you know the hostnames and want to get the address for one or more of them, Tcl has a really cool list-array functionality. Let's say you did the code above:
Code:
set fid [open <filename> r]
set linelist [split [read $fid] \n]
close $fid
Now linelist looks like:
hostname1 addr1 hostname2 addr2 ...
If you turn linelist into an array, say linearray:
array set linearray $linelist
you can now index linearray with hostname:
% set linearray(hostname1)
addr1



_________________
Bob Rashkin
 
Oops. I led you astray there. linelist will look like: {hostname1 addr1} {hostname2 addr2} ..., because of the spaces. So first you have to get rid of the braces:
Code:
foreach line $linelist {
     foreach elm $line {lappend linelist2 $elm}
}


_________________
Bob Rashkin
 
Thanks for everything. This has definitly made a difference for me. My script is looking pretty good with a few small final touches left. Expect/TCL is pretty cool!

Free Firewall/Network/Systems Support-
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top