Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
Think about Loose Coupling
 
PerlMonks  

replacing the last portions of an octet

by diamondsandperls (Beadle)
on Sep 18, 2012 at 19:29 UTC ( #994338=perlquestion: print w/ replies, xml ) Need Help??
diamondsandperls has asked for the wisdom of the Perl Monks concerning the following question:

I need to subtract one digit from the last octet of the first ip and i need to add one to the last octet of the second ip address.

I am obviously struggling with this as my current code will dictate.

SAMPLE STRING: 192.168.1.1-192.168.1.254 needs to be 192.168.1.0-192.168.1.255

I have many strings of text that are random but the format is similar but the sample string can be 172.15.29.21-172.15.30.23 needs to be 172.15.29.20-172.15.30.24. These are all made up. In the first octet there will never be a zero as the last digit so only the very last digit in the octet needs to be regexed and subracted.

#!C:/Perl/bin/perl.exe use strict; use warnings; my $ip_1 =~ m/(\d)-/g; $ip_1 = int($ip_1); my $ip_2 = $ip_1 - 1; my $input_file = 'CrystalReportViewer1.csv'; my $output_file = 'CrystalReportViewer2.csv'; open(my $output_fh, '>', $output_file) or die "Failed to open $output_file - $!"; open(my $input_fh, '<', $input_file) or die "Failed to open $input_file: $!"; while ( <$input_fh> ) { s/$ip_1/$ip_2/; print {$output_fh} $_; } close $output_fh;

Comment on replacing the last portions of an octet
Download Code
Re: replacing the last portions of an octet
by blue_cowdawg (Prior) on Sep 18, 2012 at 19:40 UTC

    Something like this?

    #!/usr/bin/perl -w use strict; my $ips='192.168.1.1-192.168.1.254'; my ($first,$second)=split('-',$ips); printf "%s-%s\n",$first,$second; $first = incip($first); $second = incip($second); printf "%s-%s\n",$first,$second; exit(0); sub incip { my $ip=shift; my @o=split(/[\.]/,$ip); $o[3]++; return sprintf("%d.%d.%d.%d",@o); }


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
      sorry just noticed those are subroutines ill play around some more
      thanks was able to play around with your sample code to get what i was looking for thanks for the heads up and insight
Re: replacing the last portions of an octet
by ksublondie (Pilgrim) on Sep 18, 2012 at 19:57 UTC
    ...You'll probably need to test that the last number in each octet is 0 <= x <= 255 after the arithmetic...
      good point this will not be needed as none of the numbers ever are this however the first ip needs to decrease and the sample code increases both how do i decrease a wild guess was decip but that did not work
Re: replacing the last portions of an octet
by Kenosis (Priest) on Sep 18, 2012 at 20:14 UTC

    Here's another option:

    use Modern::Perl; my $IPs = '192.168.1.1-192.168.1.254'; $IPs =~ s/(.+\.)(\d+)(\s*-\s*.+\.)(\d+)/$1 . ($2 - 1) . $3 . ($4 + 1)/ +e; say $IPs;

    Output:

    192.168.1.0-192.168.1.255
Re: replacing the last portions of an octet
by atcroft (Monsignor) on Sep 18, 2012 at 20:37 UTC

    Here were two functions I wrote (before I found out about things like Net::IP or NetAddr::IP that you might find helpful:

    sub dq2number { my $ip = shift; return unpack "N", pack "C4", split /\D/, $ip; } sub number2dq { my $n = shift; return join q{.}, unpack "C4", pack "N", $n; }

    Here is an example, so you can see the result

    use strict; use warnings; my @c = qw/ 0.0.0.0 0.255.255.255 10.0.0.1 172.16.0.1 127.0.0.1 192.168.0.1 /; foreach my $d (@c) { print $d, q{ }, number2dq( dq2number( $d ) - 1 ), q{ }, number2dq( dq2number( $d ) + 1 ), qq{\n}; } sub dq2number { my $ip = shift; return unpack "N", pack "C4", split /\D/, $ip; } sub number2dq { my $n = shift; return join q{.}, unpack "C4", pack "N", $n; } # Output: # 0.0.0.0 255.255.255.255 0.0.0.1 # 0.255.255.255 0.255.255.254 1.0.0.0 # 10.0.0.1 10.0.0.0 10.0.0.2 # 172.16.0.1 172.16.0.0 172.16.0.2 # 127.0.0.1 127.0.0.0 127.0.0.2 # 192.168.0.1 192.168.0.0 192.168.0.2

    Hope that helps.

Re: replacing the last portions of an octet
by AnomalousMonk (Monsignor) on Sep 19, 2012 at 02:27 UTC

    An example using the IP decimal octet regex from Regexp::Common's friend Regexp::Common::net:

    >perl -wMstrict -le "use Regexp::Common qw(net); ;; my $s = shift; print qq{'$s'}; ;; $s =~ s{ \b ($RE{net}{IPv4}) - ($RE{net}{IPv4}) \b } { add_oct($1, -1) . '-' . add_oct($2, +1) }xmse; print qq{'$s'}; ;; sub add_oct { (my $ip = $_[0]) =~ s{ (\d+) \z }{ ($1 + $_[1]) & 0xff }xmse; return $ip; } " "192.168.1.1-192.168.1.255" '192.168.1.1-192.168.1.255' '192.168.1.0-192.168.1.0'

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2014-04-20 02:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (485 votes), past polls