Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

persistent new line

by enkibian (Initiate)
on Feb 15, 2012 at 14:40 UTC ( #953966=perlquestion: print w/replies, xml ) Need Help??
enkibian has asked for the wisdom of the Perl Monks concerning the following question:

welcome Perl Worshippers

please tell me why I am getting new line after printing $line variable?

sorry for maybe messed code :P, asterisks and @ just to show in print what's happening, need to run in on Linux and create ipchanges.log before

#! /usr/bin/perl while (1){ unlink ("index.html"); $content = `wget -nv`; open FILE,"index.html"; @content = <FILE>; close FILE; open DATA, ">>ipchanges.log"; foreach $line(@content){ if ($line =~ "<title>"){ $line =~ s/://g; $line =~ s/<title>//g; $line =~ s/<\/title>//g; $line =~ s/ //g; $line =~ s/What'sMyIP-YourIPis//g; $data = `date`; chomp $data; chomp $line; $line =~ s/\t//g; $line =~ s/\n//g; if ($line !~ $oldip) { print DATA "***$data***@***$line***CHANGED* +**\n"} else {print DATA "***$data***@***$line***SAME***\n"} $oldip = $line; } } sleep 60; close DATA; }

Replies are listed 'Best First'.
Re: persistent new line
by AR (Friar) on Feb 15, 2012 at 15:46 UTC

    Because you need to chomp your lines.

    I didn't read the code closely enough.

      Yes, exactly. But even better than chomp, IMHO, is just s/\s+$//, particularly since elsewhere the specter of "\r\n" was noted (not implementing something that breaks in the face of other forms of trailing whitespace is also a big "win").

      - tye        

      Isn't this bit chomping this variable?

      chomp $line;
        Yes. I didn't read too closely.
Re: persistent new line
by VinsWorldcom (Parson) on Feb 15, 2012 at 15:50 UTC

    Other than the obvious recommendations of 'use strict; use warnings;', the 3-argument preferred call to 'open' and the fact that $oldip won't be defined the first time through, it works for me on Windows:

    vincen_m@C:\Users\vincen_m\tmp> SYSTEM_WGETRC = c:/progra~1/wget/etc/wgetrc syswgetrc = c:/progra~1/wget/etc/wgetrc 2012-02-15 10:42:07 URL: [6184] -> "index.html" [ +1] SYSTEM_WGETRC = c:/progra~1/wget/etc/wgetrc syswgetrc = c:/progra~1/wget/etc/wgetrc 2012-02-15 10:42:12 URL: [6184] -> "index.html" [ +1] ...

    With output in 'ipchanges.log' of:

    vincen_m@C:\Users\vincen_m\tmp> tail -f ipchanges.log ***Wednesday February 15, 2012 10:42:07 AM Eastern Standard Time***@** +****CHANGED*** ***Wednesday February 15, 2012 10:42:12 AM Eastern Standard Time***@** +****SAME*** ***Wednesday February 15, 2012 10:42:18 AM Eastern Standard Time***@** +****SAME*** ...

    NOTE: My IP was manually change in output before posting this, I had to change the 'date' command to 'clock.exe' which is a program I have that emulates the *nix 'date' command as Windows has a 'date' command that does something different and I have 'wget.exe' for Windows installed.

Re: persistent new line
by trizen (Hermit) on Feb 15, 2012 at 17:24 UTC
    Lines are ending with '\r\n', so the following code might help:
    open FILE, '<:crlf', 'index.html'

    Anyway, I would suggest the following script:
    #!/usr/bin/perl use strict; use warnings; require LWP::UserAgent; my $ua = LWP::UserAgent->new( keep_alive => 1, env_proxy => 1, show_progress => 1, ); my $log_file = 'ipchanges.log'; open my $data_fh, '>>', $log_file or die "Unable to append to $log_fil +e: $!"; my $old_fh = select($data_fh); ++$|; select $old_fh; my $old_ip = ''; # your current ip while (1) { my $ip = ''; if ($ua->get('')->content =~ m{^<title>What's +My IP - Your IP is: ([\d.]+)}mi) { $ip = $1; printf {$data_fh} "***%s***@***%s***%s***\n", scalar localtime +(time), $ip, $ip eq $old_ip ? 'SAME' : 'CHANGED'; } $old_ip = $ip; sleep 60; }
Re: persistent new line
by enkibian (Initiate) on Feb 16, 2012 at 00:30 UTC

    First of all thank you all for response, Perl wisdom shall be with you :P

    Solution was to add:   $line =~ s/\r//g;

    In response to answers:

    1. Isn't  chomp $line; chomping this line?

    2. I know that the proper way is to use strict and warnings - thanks for remaining me I need to get use to use it (sounds funny).

    3. I tend to keep things simple in meaning of understanding from "just look" approach this is why I am not using any library's like LWP::UserAgent etc. if its not making me writing faster and can be replaced with more simple code in my opinion.

      chomp only bites off the last character of the string. Windows is using \r\n for newlines. So, from porting point of view, using s/\r?\n$//g is much more portable.

      Another solution would be using chomp in combination with an conditional chop

        chomp only bites off the last character of the string

        That is not strictly true. Clearly on Windows, a chomp will remove both the CR and the LF - that's 2 characters! On Windows the IO layer is expecting CRLF terminated lines and it just automatically assumes that when opening a file in text mode. On Unix, trizen's suggestion of: open FILE, '<:crlf', 'index.html' looks like it would also work. Having said that, I don't see anything wrong with using a regex to remove whitespace from the end of the line - this approach will work fine.

        Maybe this is too "nit-picky", but this "one character" idea is not correct. In Perl "\n" is magical in that sometimes it also means CRLF instead of just the single character LF. Also consider that CRLF line endings are also used all the time on Unix!! This is the standard for network communications. So if you open a socket and write to it on any OS, these lines will also be CRLF terminated! Most of the time this stuff is pretty much transparent to the Perl programmer. This thread shows a case where it is not.

Re: persistent new line
by Karkadan (Initiate) on Feb 15, 2012 at 18:57 UTC

    Do you know about the WIMIP automation page? This could make your life much easier:

    #! /usr/bin/perl use strict; use warnings; my $oldip = ''; while (1){ my$ip = `wget -q -O +-`; my @t = localtime(); $t[5] += 1900; my $date = $t[5] . '-' . $t[4] . '-' . $t[3] . ' ' . $t[2] . ':' . + $t[1]; if ("$ip" ne "$oldip"){ print "IP changed on $date from \"$oldip\" to \"$ip\"\n"; $oldip = $ip; } else { print "IP unchanged on $date. Is: \"$ip\"\n"; } sleep 15; }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://953966]
Approved by Eliya
[Eily]: probably because I'm an underpriviledged millenial
[LanX]: oh
[LanX]: but do you have a car?

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (10)
As of 2017-03-23 17:50 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (292 votes). Check out past polls.