Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

removing a column

by jn64024 (Initiate)
on Jun 17, 2009 at 20:31 UTC ( [id://772530]=perlquestion: print w/replies, xml ) Need Help??

jn64024 has asked for the wisdom of the Perl Monks concerning the following question:

Overall I am attempting to run a socket cmd on a list of IP's. I am capturing this list of ip's from an /etc/hosts file. This file is structured as two columns. Ip's on the left and device names on the right seperated by a tab. The following code skips commented lines, pulls out any spaces between lines and pushes it into an array for eventual sorting, removal of duplicates and then running the socket cmd against the final list. I however cannot figure out how to remove the second column from the array.

My print cmds are for testing only to view my output. Here is what I have so far. Anythoughts on how I can remove the second column from the array?

#!/usr/bin/perl use strict; use Socket; my ( @hostcontents ,@uniquearray ,@ipaddresses ,@linesplit ,@line ) = (); my $line = (); my $hostfile = "/tmp/jn/hosts"; my %seen=(); my $logfile = "/tmp/jn/logforthisserver.log"; open(HOSTFILE,"<$hostfile"); foreach (<HOSTFILE>){ if($_ =~ m/^#/){next;} if($_ =~ m/^\s$/){next;} push (@hostcontents,$_); } close(HOSTFILE); print "Current hostcontents:\n@hostcontents\n"; foreach my $temp (@hostcontents){ #print "my line is: $line"; #@linesplit = split($split,$line); #@linesplit = split(/\t+/,$line); #@linesplit = split(" ",$line); #@linesplit = split(/\s+/, $_)[0]; #print "Test:$line"; } #print "Current linesplit:\n@linesplit\n"; #foreach $line (@linesplit) { # next if $seen{$line}++; # push(@uniquearray,$line); # $seen{$line}++; # print"Seen Hash is:\n @{[ %seen ]}\n"; #} #Sort the array @uniquearray=sort(@uniquearray); #foreach my $line (@uniquearray){ # print "$line"; #SOCKET JUNK #} # open (LOGFILE,">$logfile"); # print LOGFILE (@ipaddresses); # close(LOGFILE); #}#end foreach

Replies are listed 'Best First'.
Re: removing a column
by toolic (Bishop) on Jun 17, 2009 at 20:50 UTC
    It sounds like you only want to keep the first column of the /etc/hosts file. In that case, you can use the default behavior of split to split the lines on any whitespace, then just push the 1st element (column) into your array. Data::Dumper is just used for simple print-out:
    use strict; use warnings; use Data::Dumper; my @ips; while (<DATA>) { next if /^#/; next if /^\s*$/; push @ips, (split)[0]; } print Dumper(\@ips); __DATA__ # comments: phony ip's 666.6.6.66 foo.bar 77.77.77.77 goo

    prints:

    $VAR1 = [ '666.6.6.66', '77.77.77.77' ];
Re: removing a column
by johngg (Canon) on Jun 17, 2009 at 22:47 UTC

    It is a good idea to check for the success of your opens and closes and to use the three argument form for open with lexical filehandles. You should also use single quotes if you don't need interpolation.

    my $hostfile = '/tmp/jn/hosts'; open my $hostFH, '<', $hostfile or die "open: < $hostfile: $!\n";
    You need to take care when sorting IPs as a simple lexical sort will give odd results.

    $ perl -le ' > @IPs = qw{ 22.32.87.12 56.67.38.61 101.12.34.54 }; > print for sort @IPs;' 101.12.34.54 22.32.87.12 56.67.38.61 $

    I use sprintf here to form each quad into a fixed width string with leading zeros, making a 12-digit string that can be sorted lexically.

    use strict; use warnings; my %seen; my @sortedUniques = map { ( split m{\s+}, $_->[ 0 ] )[ 0 ] } sort { $a->[ 1 ] cmp $b->[ 1 ] } grep { ! $seen{ $_->[ 1 ] } ++ } map { m{^(\d+)\.(\d+)\.(\d+)\.(\d+)\t} ? [ $_, sprintf q{%03d%03d%03d%03d}, $1, $2, $3, $4 ] : () } <DATA>; print qq{$_\n} for @sortedUniques; __END__ # hosts file 10.31.17.65 fw2 192.168.1.78 hosta 192.168.1.21 hostb 10.31.17.65 fw2dup 10.23.212.6 hostc 192.168.100.254 fw1 192.168.1.21 hostbdup

    The output.

    10.23.212.6 10.31.17.65 192.168.1.21 192.168.1.78 192.168.100.254

    I hope this is helpful.

    Cheers,

    JohnGG

        All, Thank you for the information....I have taken all in consideration to finish off what I have.

        I love this language as it just shows above how many different ways the same thing can be completed along with all the considerations in error checking.

        Again thank you all very much!

Re: removing a column
by VinsWorldcom (Prior) on Jun 17, 2009 at 20:53 UTC
    I may be misunderstanding what you're asking, but to get only 1 column, you can just split the line as you read it.

    open(HOSTFILE,"<$hostfile"); foreach (<HOSTFILE>){ if($_ =~ m/^#/){next;} if($_ =~ m/^\s$/){next;} # Insert this line to split by whitespace my @lineParts = split (/\s+/, $_); # push (@hostcontents,$_); # Push [0] first column (ip), or use [1] for second column (hostname) push (@hostcontents,$lineParts[0]); } close(HOSTFILE);
Re: removing a column
by jwkrahn (Abbot) on Jun 17, 2009 at 22:11 UTC

    It sounds like you want something like this:

    #!/usr/bin/perl use warnings; use strict; use Socket; my $hostfile = '/tmp/jn/hosts'; my $logfile = '/tmp/jn/logforthisserver.log'; open HOSTFILE, '<', $hostfile or die "Cannot open '$hostfile' $!"; my %unique_ips; while ( <HOSTFILE> ) { next if /^(?:#|\s*$)/; my $ip = inet_aton( ( split )[ 0 ] ); $unique_ips{ $ip }++; } close HOSTFILE; open LOGFILE, '>', $logfile or die "Cannot open '$logfile' $!"; for my $ip ( sort keys %unique_ips ) { print LOGFILE inet_ntoa( $ip ), "\n"; } close LOGFILE;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://772530]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (7)
As of 2024-04-24 11:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found