By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,852 Members | 1,410 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,852 IT Pros & Developers. It's quick & easy.

Help with splitting up a input file.

P: 17
I have a text file with a list of servers and then a description of the server along with the applications that may be hosted on them. Here is a example

Expand|Select|Wrap|Line Numbers
  1. SERVER01
  2. SERVER01 Windows Server 2003 RC2. SQL server. Runs blah blah..
  3. blah. and so forth.
  4.  
  5. SERVER02
  6. SERVER02 REDHAT Linux. MAIL etc etc etc
I am trying to open up the file and parse it into an array that will only list the SERVER Names and then a hash that will have the SERVER name as the key and the description as the hash value.

I have a start of this and am trying to use a regex expression to at least find and add the servers to the array but this simply input the entire contents of the text file into the array.

Expand|Select|Wrap|Line Numbers
  1. sub ParseInputFile(){
  2. open(SERVERS, "servers.txt") || die "$!";
  3. @contents=<SERVERS>;
  4. close(SERVERS);
  5.  
  6. foreach $server (@contents){
  7.     if($server =~ /\w/){
  8.         my @server_array = (@server_array, $server);
  9.         print "Its added\n";
  10.     }
  11.  
  12. }
I figure If I get this done first i can work at then getting it into a hash or maybe even in the same step I can also split it into the hash value as well. But is there any wildcards to use this for PERL? The \w operator matches any word but how do I split my input into words then put the word into a array and then put it into a hash?

Thanks
Feb 19 '08 #1
Share this Question
Share on Google+
9 Replies


nithinpes
Expert 100+
P: 410
I am modifying your foreach loop to accomplish both tasks.

Expand|Select|Wrap|Line Numbers
  1. foreach $server (@contents){
  2.       chomp $server;
  3.       if($server =~ /^(\w+)\s+(.*)$/) {  # grouping first word&remaining words of line
  4.           $sername = $1;
  5.           $desc = $2;
  6.           push @server_array, $sername;  # array of server names
  7.           $server_hash{$sername} = $desc;   #hash of server name=>description
  8.          }    
  9.     }
  10.  
To include accidentally introduced space at the begining, you can modify your regex to:
Expand|Select|Wrap|Line Numbers
  1. if($server =~ /^\s*(\w+)\s+(.*)$/)
  2.  
I am assuming description is not spread over multiple lines.
Feb 19 '08 #2

P: 17
Thanks for the input. Unfortunately the description can be over multiple lines so that is where I am having my main problems. PERL splits each line of the input file into the array which is what is causing me the most problems. There is a blank line between each description.

I tried your suggestion but it put every word into the array. When I tried removing the chomp operator so I could use whitespace as my end point but this worked better slightly better. But since the whitespace is one or more it thinks that any space in the separation in words is my delimiter character. Is there a way to make the expression 2 or more whitespace?
Feb 19 '08 #3

eWish
Expert 100+
P: 971
As a side note, one thing that will make your script faster is if you read the file line by line rather than slurping the entire file into memory. If you want to slurp the file I would suggest that you use File::Slurp.

--Kevin
Feb 19 '08 #4

KevinADC
Expert 2.5K+
P: 4,059
Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3. use Carp;
  4. my %hash = ();
  5. my $flag = 0;
  6. my $desc;
  7. my $key;
  8. open(SERVERS, "servers.txt") or die "$!";
  9. while(<SERVERS>){
  10.    chomp;
  11.    if(/^SERVER\d+$/) {# beginning of hash record
  12.       $key = $_;      
  13.       $hash{$key} = '';
  14.       $flag = 1;
  15.       next;
  16.    }
  17.    if(/^\s*$/) { # end of hash record
  18.       $hash{$key} = $desc;
  19.       $key = ''; 
  20.       $flag = 0;
  21.       $desc = '';
  22.    }
  23.    elsif ($flag) {# value of hash record
  24.       $desc .= "$_ ";
  25.    }
  26.    else {# possible unknown condition
  27.       warn "A line I don't know what to do with: $_";
  28.    }
  29. }
  30. print "$_ $hash{$_}\n" for sort keys %hash;;
  31.  
Feb 19 '08 #5

P: 17
I got it to work sort of but could not get it to work using a FILEHANDLE. To get my regex correct I simply opened it after assigning a variable to the name of the text file then reading it in. This reads the server name into the hash key and the description as the hash value.

Expand|Select|Wrap|Line Numbers
  1. my %hash = ();
  2. my @array;
  3. my $file = "servers.txt";
  4.  
  5. open($file, "<$file");
  6.  
  7. while (<$file>) {
  8.    last if /^$/;
  9.    my $val = $_;
  10.    $hash{$val} = "";
  11.    push(@array, $_);
  12.  
  13.    while (<$file>) {
  14.      last if /^$/;
  15.      $hash{$val} .= $_;
  16.    }
  17. }
  18.  
  19. foreach (keys %hash) {
  20.    print "$_$hash{$_}\n";
  21.  
  22. }
But I cannot get this to work by using it as a filehandle. I believe this is because of the way it read in with the filehandle.

Expand|Select|Wrap|Line Numbers
  1.  open(SERVERS, "servers.txt") || die "$!";
  2.     my $contents = "<servers.txt";
  3.     close(SERVERS);
  4.  
  5.     my %hash = ();
  6.     my @array;
  7.  
  8.     while (<$contents>) {
  9.         last if /^$/;
  10.         my $desc = $_;
  11.         $hash{$desc} = "";
  12.         push(@array, $_);
  13.  
  14.         while (<$contents>) {
  15.             last if /^$/;
  16.             $hash{$desc} .= $_;
  17.     }
  18.  
  19.     foreach (keys %hash) {
  20.         print "$_$hash{$_}\n";
  21.     }
Feb 20 '08 #6

KevinADC
Expert 2.5K+
P: 4,059
Comments removed: I posted in the wrong thread, sorry
Feb 20 '08 #7

P: 17
Never mind I got it. Took me a bit but the problem I was having was the way I was reading the file. I stopped reading it into a array and then searching and simply split it up as it was being read.
Feb 21 '08 #8

eWish
Expert 100+
P: 971
The servers.txt is just a file, not a filehandle. The $contents variable is not a filehandle either.

Expand|Select|Wrap|Line Numbers
  1. open(my $FILEHANDLE, '<', $text_file) || die "Can't open file $!\n";
  2.      while (<$FILEHANDLE>) {
  3.      ...do somthing here......
  4.      }
  5. close($FILEHANDLE);
perldoc open

--Kevin
Feb 21 '08 #9

KevinADC
Expert 2.5K+
P: 4,059
Never mind I got it. Took me a bit but the problem I was having was the way I was reading the file. I stopped reading it into a array and then searching and simply split it up as it was being read.

Did you not like the code I posted earlier in the thread or did it not work? You seemed to have ignored it.
Feb 21 '08 #10

Post your reply

Sign in to post your reply or Sign up for a free account.