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

Hello your holinesses,
As my moniker implies, I am new to perl. I am trying to take input from STDIN that looks like this:
xs029
xs030
xs031
xs032
xs034

see if these hosts exist in a file and print the line in the file if they do. The contents of the file I'm searching through looks like this:

xs029 Host Node 129.202.178.129 - - - - - 10.200.178.129
xs030 Host Node 129.202.178.130 - - - - - 10.200.178.130
xs031 Host Node 129.202.178.131 - - - - - 10.200.178.131


and finally, here is my code. For some reason when I run it , it just sits there doing nothing. Any help would be much appreciated!
$infile="hosts.txt"; open(INPUT, $infile) || die "Error opening $infile\n"; my @allhosts = <INPUT>; foreach $approvhost (<STDIN>) { foreach $host (<@allhosts>) { if ($host =~ m/^$approvhost/) { print $host; } } }

Replies are listed 'Best First'.
Re: matching a line from one file in another
by Fletch (Bishop) on Apr 14, 2006 at 14:42 UTC

    The line foreach $host (<@allhosts>) is just wrong. The diamond operator is for reading from filehandles; it has nothing to do with iterating over an array. You wanted for my $host ( @allhosts ).

    Having said that, a better approach would be to rethink what you're doing and go at the problem another way.

    • Read in the list of hosts from STDIN first and stash them in a hash (e.g. my %want; while( <STDIN> ) { chomp; $want{$_} = 1 }).
    • Next read the lines of the other file and split off the first element; if that element exists $want{ $ele } then you print the line.
      I think you are probably correct, a hash would be much cleaner. I will probably rewrite accordingly (good way to teach myself how to work with hashes), thanks.
Re: matching a line from one file in another
by davidrw (Prior) on Apr 14, 2006 at 14:54 UTC
    You can also just use the *nix command-line utility join (it supports reading from STDIN) ..
    join - hosts.txt # and type/paste in the input ./some_program | join - hosts.txt # pipe the input in
      But remember that both input files need to be sorted. The examples were, but if not, you would have to sort them before the join.
Re: matching a line from one file in another
by Herkum (Parson) on Apr 14, 2006 at 14:38 UTC

    You forgot to remove the \n character when they submitting the value to STDIN. Try this,

    open(INPUT, "hosts.txt") || die "Error opening 'hosts.txt'\n"; my @hosts = <INPUT>; while (<STDIN>) { chomp($_); foreach $host (@hosts) { if ($host =~ m/^$_/) { print "Host found: '$host'\n"; } } }

    As someone pointed out, the foreach should not be used with the STDIN and the brackets around @allhosts was wrong too. Fixed.

      Thank you for your speedy reply, it is now doing what I need it to!
Re: matching a line from one file in another
by davido (Cardinal) on Apr 14, 2006 at 15:54 UTC

    As my moniker implies, I am new to perl.

    Being new to Perl is a temporary condition, and monikers generally are not. How would life go if your parents had named you "Newborn"? ;)


    Dave

Re: matching a line from one file in another
by cormanaz (Deacon) on Apr 15, 2006 at 00:20 UTC
    I didn't test this, but I think what you want is:
    $infile="hosts.txt"; open(INPUT, $infile) || die "Error opening $infile\n"; my @allhosts = <INPUT>; close INPUT; while ($approvhost=<STDIN>) { chop($approvedhost); # or it won't partially match # your hosts entries becaus of # the training \n unless ($approvedhost) { last; } # so you can quit # with a null entry foreach $host (@allhosts) # omit the <> you're not # reading a file or stdin { if ($host =~ m/^$approvhost/) { print $host; } } }