Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

The Monastery Gates

( #131=superdoc: print w/ replies, xml ) Need Help??

Donations gladly accepted

If you're new here please read PerlMonks FAQ
and Create a new user.

New Questions
port check
2 direct replies — Read more / Contribute
by deelinux
on Nov 28, 2015 at 08:06

    Hi I want to do some port checks (http and tcp) on an array of servers

    I'm still new to Perl/Programming, and found in the perldoc Net::Ping, from which I have created some ping checks, along with code found on the net, but would like some guidance on how I could ping check and then test if some specific ports are available

    I have created an array to ping some servers, which is fine, but Id like to create a sub function to check an array of ports.

    sub ping_servers { foreach $host (@my_servers) { my $p = Net::Ping ->new("icmp"); #create ping object my $res = $p -> ping ($host); #ping the hosts from array list $output .= "Unknown host $host\n" unless defined $resolve; if (!$res) { $output .= "$host doesn't respond to ping requests!\n" +; } else { $output .= "$host is alive.\n"; } } }

    I's also like to understand what this "->" means in code?

    Any know how, or pointers would be great.

Validate Ip address Regexp
6 direct replies — Read more / Contribute
by akr8986
on Nov 28, 2015 at 06:48

    hi i am new to perl and was trying to write a script to check if ip address is valid. Though i found some solutions online i wanted to try it on my own

    #! /usr/bin/perl -w
    print "Enter IP Address:"; my $ip = <STDIN>; if ( $ip =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/) { print "yes match $1 $2 $3 $4\n"; } else { print "no match\n"; }

    when i enter it says ip address matches as expected. But when enter 1000.3.4.5 too it says match is found and the values of $1 to $4 are printed as 000 3 4 5. How could this happen as i am saying to match only 3 digits and not more than that using "\d{1-3}" englighten me!

Best way to handle interactive user input?
4 direct replies — Read more / Contribute
by Ppeoc
on Nov 26, 2015 at 02:02
    I have a huge XML file to parse. I was thinking that instead of parsing the whole file, I could ask the user to input a few options and then parse only that portion of the file. I was basically planning to do this
    Enter option to be parsed 1. Fiction 2. History 3. Religion 10. Non fiction

    So once the user enters the number 2, Book 2 will get selected and bunch of other options will be displayed as follows

    Selected Book 2. Options are as follow 1. World History 2. American History 3. Oriental History 10. Indian History

    Each option is nested differently with different levels. The plan is to use a switch statement on the returned $_ to display options for the next level. How do I navigate to a different part of the program and display options according to the genre selected. Thanks!

    use strict; use warnings; use Switch; my $level1; print "Select options: \n 1 Fiction \n 2 History \n 3 Religion \n"; my $no = getIP('Enter a digit : ', /^\d/); switch ($no) { case 1 { $level1 = ?? } case 2 { $level1 = ?? } case 3 { $level1 = ?? } else { $level1= ?? } } print $level1; sub getIP { print $_[0]; do { $_ = <STDIN>; chomp; } while ($_[1] && $_ !~ $_[1]); return $_; }
Check a string for consecutive digits
6 direct replies — Read more / Contribute
by Anonymous Monk
on Nov 25, 2015 at 17:38

    Greetings, keepers of knowledge.

    I'm putting together a password checking script for Asterisk voicemail; one of the things I want to disallow is the use of a password that's got too many consecutive digits. "1234" being the classic example, but also "298761" or "4562".

    PHP is my usual language, but it's not available, so I went with Perl, since I used it many years ago, and the two share a lot of common syntax. The code I have works, but I feel like there should be a better way, that doesn't take so many lines of code to go through every digit twice.

    my $password = $2; my $limit = 3; # want to reject 4568 but not 4578 my $counter = 0; my $i = 0; my @digits = split(//, $password); my $pwlength = @digits; for ($i = 0; $i < $pwlength - 1; $i++) { if ($digits[$i] + 1 == $digits[$i + 1]) { $counter += 1; } else { $counter = 0; } if ($counter >= $limit) { exit 1; } } $counter = 0; for ($i = 0; $i < $pwlength - 1; $i++) { if ($digits[$i] - 1 == $digits[$i + 1]) { $counter += 1; } else { $counter = 0; } if ($counter >= $limit) { exit 1; } }
[closed] map sentence as array slice indexes
2 direct replies — Read more / Contribute
by rsFalse
on Nov 25, 2015 at 06:43

    I tried to understand why the following (with map sentence) gives an error. Can't understand.
    use warnings; use strict; @_ = 'a' .. 'c'; print @_[ map $_ -1, grep { $_ > 0 and $_ <= 1 } map { $_ + 1 } -1 .. 1 ];
    Missing comma after first argument to map function at map_inside_splic line 12, near "]"
    And the following (with map block) don't give an error:
    use warnings; use strict; @_ = 'a' .. 'c'; print @_[ map {$_ -1} grep { $_ > 0 and $_ <= 1 } map { $_ + 1 } -1 .. 1 ];
    upd: thanks for answers below.
using Linux getdents syscall
5 direct replies — Read more / Contribute
by glasswalk3r
on Nov 23, 2015 at 18:37

    Hello monks,

    I'm looking for a fast way to list the contents of a directory (with thousands of files) on Linux by using Perl.

    I did some research on that and found a sample C code that uses the getdents system call for that. By using it, one can avoid calling stat on each file inside the directory (basically what ls command does).

    I did some tests with readdir, but performance speed compared to the already mentioned C code as good. That said, I'm inclined to try to use Perl syscall to do the same. Below is the C code (for those inclined to read it):

    This is how the C struct should look like:

    struct linux_dirent { unsigned long d_ino; /* Inode number 32*/ unsigned long d_off; /* Offset to next linux_dirent 32*/ unsigned short d_reclen; /* Length of this linux_dirent 16*/ char d_name[]; /* Filename (null-terminated) */ /* length is actually (d_reclen - 2 - offsetof(struct linux_dirent, d_name)) */ }

    Since I'm not a C programmer, I struggling to achieve that. I found that I need to use unpack to retrieve the information from the related C struct, but I'm lost about:

    • Finding out the lenght I need to setup the Perl equivalent to the buffer (a scalar set with NUL characters, as my $buffer = "\0" x 64;), specially because the related C structure has a char array with dynamic length
    • The buffer will retain a N number of dentries inside of it. How can I find the exactly number of bytes each dentrie has and how can I jump from one entry to the other with Perl?

    Is it even possible to do that without having to use XS (or any of it's alternatives)? I found Convert::Binary::C to give a hand, but probably I'm not using it correctly due the 2 issues above. If I use Data::Dumper on the buffer, I can see the file names, but got only garbage from Convert::Binary::C.

    Here is my (not working) Perl code implementation:


    Alceu Rodrigues de Freitas Junior
    "You have enemies? Good. That means you've stood up for something, sometime in your life." - Sir Winston Churchill
Initialize multiple variables in one statement
5 direct replies — Read more / Contribute
by Anonymous Monk
on Nov 23, 2015 at 13:56
    Hi there Monks!

    Is here a better way to initialize multiple variables in one statement other than this?
    ... my ($name1, $name2, $name3, $name4, $name5, $name6); $name1 = $name2 = $name3 = $name4 = $name5 = $name6 = ''; print "\n $name1, $name2, $name3, $name4, $name5, $name6\n\n"; ...

copy line with character
1 direct reply — Read more / Contribute
by jalopez453
on Nov 23, 2015 at 13:32

    Hello everyone, I am looking for a little help on my code here. I want to copy the lines that have the letter M in the first column but not sure what I am doing wrong or what is missing. I am very new to perl, so I apologize for this very basic request. Thank you in advance for the help

    use strict; my $find = 'M'; open (NEW, ">", "output.txt" ) or die "could not open:$!"; open (FILE, "<", "Report.txt") or die "could not open:$!"; while (<FILE>) { print NEW if (/$find/); } close (FILE); close (NEW);
Problem in creating process
5 direct replies — Read more / Contribute
by ravi45722
on Nov 23, 2015 at 00:42

    I write a code normally and its taking 186 wall clocks to read the total files. To reduce the time I created process and split my load for two process. After creating process its taking 261 wall clock seconds. What's the mistake I am doing?? I think by creating process and running it parallel may reduce the execution time. But its increased. How???

    sub SMSBcastCDR { #doing operation on files } sub SMSCDR { #doing operation on files } LINKS: foreach my $linkarray (1 .. 2) { $pm->start and next LINKS; # do the fork if ($first == 1) { my @cdr_list1 = `ls $cdr_directory/SMSBcastCDR_*_$bcat_cdrdate +\_*.log`; print "cdrs_file1 = @cdr_list1\n"; SMSBcastCDR(@cdr_list1); $first++; } if ($first == 2) { my @smsc_cdr_list=`ls $smscdr_directory/SMSCDR_P*_$cdr +date*.log`; SMSCDR(@smsc_cdr_list); } $pm->finish; # do the exit in the child process } $pm->wait_all_children;
New Meditations
Something that bugs me about the Numeric class hierarchy in Perl 6
1 direct reply — Read more / Contribute
by grondilu
on Nov 24, 2015 at 03:16

    Hello Monks,

    This is something that has bugged some times to times : I have the feeling that the class hierarchy for numeric types in Perl 6 is upside down.

    Let me give you an example. The other day I wrote on rosetta code the following function to compute binomial coefficients:

    sub infix:<choose> { [*] ($^n ... 0) Z/ 1 .. $^p } say 5 choose 3;

    I was quite happy about it, until I realized that the output was of type Rat, not Int. So I had to make an explicit conversion:

    sub infix:<choose> { ([*] ($^n ... 0) Z/ 1 .. $^p).Int }

    That was a bit annoying. Frankly, I expect something like 10/5 to be an integer, not a rational. I mean, I know it is a rational, but it also is an integer. Because normally in math, all integers are rationals. Their denominator is just 1.

    Things don't work like this in Perl 6. Numeric types are more about implementation than mathematics. Yet there is a feature in Perl 6 that could be used to make things work more like in math:

    subset Int of Rat where [%%] *.nude;

    If Int was defined as such, integers would be particular cases of rationals. In the same way, real numbers would be special cases of complex numbers:

    subset Real of Complex where { $_ == .conj };

    An other possibility would be:

    role Int does Rational { method nude { self, 1 }; ... }

    Or something like that, I don't know. Neither do I know if it would be possible or desirable to rewrite the whole Numeric hierarchy. Maybe it would not be worth the effort. But I do find it annoying that an Integer is not a Rat, or a Real not a Complex.

"Indirect" object syntax?
3 direct replies — Read more / Contribute
by muba
on Nov 22, 2015 at 21:30

    Disclaimer: IANAL. I am not a lawyer linguist.

    The syntax of (for example) $cgi = new CGI; is called indirect object syntax, which is also said to be in the dative case. Are these actually the correct designations?

New Cool Uses for Perl
Restarting File::Find
1 direct reply — Read more / Contribute
by Preceptor
on Nov 24, 2015 at 06:44

    One of the problems I've had in the past, is a need to walk a filesystem and 'batch up' files. There's a variety of reasons why - things like archiving, virus scanning, etc. Now, you _could_ do it the heavyweight way - collect a full tree directory structure, batch up that way. This didn't suit my needs - I've a billion ish files to inspect, and they change rather frequently.

    So as a workaround - make use of File::Find and it's ability to prune

    #!/usr/bin/env perl use strict; use warnings; use File::Find; my $start_from = "/path/to/search/some_dir/beneath"; my $count = 10_000; #how many files to grab in this 'batch'; my @file_list; sub finder { if ( defined $start_from and not $found ) { #partial match, walk directory. if ( $start_from =~ m/\QFile::Find::name/ ) { $File::Find::prune = 0; if ( $File::Find::name =~ m/\Q$start_from/ ) { $found = 1; } } else { $File::Find::prune = 1; #don't traverse into this dir } } if ( @file_list > $limit ) { $found = 0; $File::Find::prune = 1; return; } return unless -f $File::Find::name; push ( @file_list, $File::Find::name ); #backtracks a bit to the start of the current directory $start_from = $File::Find::dir; } find ( \&finder, '/path/to/search' ); print "Next start point: $start_from\n";

    Note - as it stands, this has a limiting factor in that it'll misbehaving if the directory structure changes (e.g. $start_from no longer exists. The workaround is chopping path elements off the end until you get to a dir that _does_ exist.

    Probably something like:

    while ( not -d $start_from and $start_from =~ m,/, ) { $start_from =~ s,/[^/]+$,,; }

    (There's probably a better solution using File::Spec or similar)

Log In?

What's my password?
Create A New User
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (6)
As of 2015-11-28 23:24 GMT
Find Nodes?
    Voting Booth?

    What would be the most significant thing to happen if a rope (or wire) tied the Earth and the Moon together?

    Results (746 votes), past polls