in reply to Re: Print word from text file that is not an exact match
in thread Print word from text file that is not an exact match

Hi Laurent, The text file is a dump of a query and looks something like this:
<Answer type="string">ServerName1.org</Answer> <Answer type="string">ServerName2.org</Answer> <Answer type="string">ServerName3.org</Answer>
Regards, Tony

Replies are listed 'Best First'.
Re^3: Print word from text file that is not an exact match
by Laurent_R (Canon) on Jun 10, 2018 at 09:03 UTC
    A regex capture, as shown by NetWallah and poj, is the easiest solution with your data.

    Let me, however, continue with my earlier idea and show how split could be used in such a case. The following is a demonstration under the Perl debugger:

    DB<1> $string = '<Answer type="string">ServerName.FD.net.org</Answer +>'; DB<2> @fields = split /[<>]/, $string; DB<3> x @fields; # displaying the content of the @fields array +after the split 0 '' 1 'Answer type="string"' 2 'ServerName.FD.net.org' 3 '/Answer' DB<4> print $fields[2]; # outputting the server name ServerName.FD.net.org
    You could also retrieve directly the server name without using a temporary array:
    DB<1> $string = '<Answer type="string">ServerName.FD.net.org</Answer +>'; DB<2> $name = (split /[<>]/, $string)[2]; DB<3> print $name; ServerName.FD.net.org
    But, again, a regex capture is simpler with your data format.
      Hi Laurent, I think I understand what you are explaining to me but would not know how to incorporate your example into the following code:
      #!/usr/bin/perl use strict; my $count = 0; my $namefile = $ARGV[0] || 'names.txt'; # default if no argument # names.txt #ServerName1 #ServerName2 # get list of computers to search for my @computers; open FILE,'<',$namefile or die "Could not open $namefile : $!"; while (<FILE>){ chomp; s/^\s+|\s+$//g; # trim spaces next unless /\S/; # skip blank lines push @computers,$_; } close FILE; my $file = "computernames.txt"; # computernames.txt #<Answer type="string">ServerName1.FD.net.org</Answer> #<Answer type="string">ServerName2.FD.net.org</Answer> #<Answer type="string">ServerName3.FD.net.org</Answer> # search text file open IN, '<',$file or die "Could not open $file : $!"; while (my $line = <IN>){ # repeat line search for each computer foreach my $search (@computers) { if ( my ($name) = $line =~ /($search[\.\w]*)/ ){ print "Name ; $name\n"; ++$count; } } } close IN; # result if ($count){ print "$count matches\n"; } else { print "No matches found\n"; }
      Thanks, Tony
        Hi Tony,

        this is an example of how you could do it, by modifying your second while loop (untested):

        while (my $line = <IN>){ my $server_name = (split /[<>]/, $line)[2]; foreach my $search (@computers) { print "Name ; $server_name\n" if $search eq $server_name; } }
        Please note, however, that using a hash, rather than an array, for storing the computers would certainly be more efficient (especially if you have a lot of data).

        Change the first part of the script as follows:

        my %computers; open FILE, '<', $namefile or die "Could not open $namefile : $!"; while (<FILE>){ chomp; s/^\s+|\s+$//g; # trim spaces next unless /\S/; # skip blank lines $computers{$_} = 1; } close FILE;
        Then change the second while loop as follows:
        while (my $line = <IN>){ my $server_name = (split /[<>]/, $line)[2]; print "Name ; $server_name\n" if exists $computers{$server_name}; }
        The point is that a hash lookup (in %computers) is usually much faster than traversing a full array (@computers) every time.