http://qs1969.pair.com?node_id=1183156

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

hi I'm using this code

#!/usr/bin/perl use IO::Socket; my $ip = $ARGV[0]; my $port=$ARGV[1]; open DAT,$in_file2; my @ip=<DAT>; close DAT; chomp(@ip); foreach my $ip(@ip) { $host = IO::Socket::INET->new( PeerAddr=>$ip, PeerPort=>$port, proto =>'tcp', Timeout=> 0.01, ) and open(OUT, ">>port.txt"); print OUT "\n$ip:$port\n"; close(OUT); }

it's printing the result like this

192.168.1.2 :22 192.168.1.2 :22 192.168.1.2 :22 192.168.1.2 :22

but i want it to print it like this

192.168.1.2:22 192.168.1.2:22 192.168.1.2:22 192.168.1.2:22 192.168.1.2:22 192.168.1.2:22 192.168.1.2:22 192.168.1.2:22 192.168.1.2:22 192.168.1.2:22 192.168.1.2:22 192.168.1.2:22
plz help me

Replies are listed 'Best First'.
Re: problem in printing the result in the out put file
by Eily (Monsignor) on Feb 28, 2017 at 16:22 UTC

    Your input data probably contains an extra \r that is not removed by chomp. You can see that with Data::Dump:

    use Data::Dump qw( pp ); # some code here print pp \@ip; chomp(@ip); print pp \@ip;
    One of the ways this can happen is when you try to read a file created on Windows with perl running on Linux, or a Cygwin perl.

    You can correct that by explicitly setting the input record separator to the CRLF format:

    my @ip; { local $/ = "\r\n"; # because this is local, the normal behaviour is +restored after this block open my $dat, "<", $in_file or die "Can't open file $in_file: $!"; @ip = <$dat>; chomp(@ip); close $dat; }

      Another way to correct it is to use open with the :crlf IO layer (if that's the correct term):

      johngg@shiraz:~/perl/Monks > perl -Mstrict -Mwarnings -E ' my $file = qq{Line 1\r\nLine 2\r\nLine 3\r\n}; open my $inFH, q{<:crlf}, \ $file or die $!; while ( <$inFH> ) { chomp; say qq{>$_<}; } close $inFH or die $!;' >Line 1< >Line 2< >Line 3<

      I hope this is of interest.

      Cheers,

      JohnGG

        I hope this is of interest

        It sure is! I actually find this method better than modifying $/, it is easier to understand and you don't have to worry about contaminating the way other handles are read. I did read about it a while ago, but I had completely forgotten this is something you can do, thanks for the reminder.

Re: problem in printing the result in the out put file
by toolic (Bishop) on Feb 28, 2017 at 16:18 UTC
Re: problem in printing the result in the out put file
by marto (Cardinal) on Feb 28, 2017 at 16:35 UTC

    Are you sure this is your code? $in_file2 isn't defined anywhere. Add use strict; use warnings;, fix the warnings given. Do you really have an and open(OUT, ">>port.txt"); for my $host = ....? You may also want to be careful with the scope of $ip, e.g.

    my $ip = 1; my @ip = qw (2 3 4); foreach my $ip (@ip){ print "$ip\n"; } print "$ip\n";

    Update: fixed code tag typo, thanks Eily.

Re: problem in printing the result in the out put file
by thanos1983 (Parson) on Feb 28, 2017 at 16:30 UTC

    Hello hegaa,

    Also another quick tip Don't Open Files in the old way. Open them in the new way (open)

    Did not test the code.

    open(my $out, '>>', 'port.txt') or die "Can't open < port.txt: $!"; print $out "\n$ip:$port\n"; close($out) or die "Can't close < port.txt: $!";;
    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: problem in printing the result in the out put file
by RonW (Parson) on Mar 02, 2017 at 21:43 UTC

    I use a similar approach to toolic's suggestion, except I specifically target line endings and anchor the pattern:

    s/[\n\r]+$// for (@ip);

    Most of the time, this is enough, because when I "export" text files to Ms Windows users, I use unix2dos to convert the line endings to MS Windows convention.

    When I want or need a tool that robustly works under both MS Windows and Linux/Unix/POSIX, I would combine that with Eily's suggestion and add in ':raw' mode, like:

    my @ip; { local $/ = "\n"; open my $dat, "<:raw", $in_file or die "Can't open file $in_file: $! +"; @ip = <$dat>; s/[\n\r]+$// for (@ip); close $dat; }

    (There's probably a module on CPAN that does this, and maybe even add support for legacy MacOS line endings.)