Re: perl and pattern

2012-02-23 Thread Igor Dovgiy
2012/2/23 Rob Dixon rob.di...@gmx.com


 Negative numbers aside, it seems more straightforward to insist that
 there are no non-digit numbers in the input, hence


That's definitely an option, but I'm not in favor of 'double negation'
conditionals usually, as they might be confusing.
For example, I use unless only when its question is simple and... a kind
of predictable. Like that:

exit unless $result =~ /^[0-9]+$/

That's definitely an overkill for me:

unless ($result !~ /[^0-9]/) { ... }

...especially because it can be safely turned to ...

if ($result =~ /[^0-9]/) { ... }

As for /\D/, well, I'd prefer to use it only with /a modifier, the reasons
discussed earlier at this thread. )

-- iD


Re: Sending files efficiently with Net::SMTP

2012-02-23 Thread Igor Dovgiy
From the documentation (http://perldoc.perl.org/Net/SMTP.html)
...
data ( [ DATA ] ) - initiate the sending of the data from the current
message. DATA may be a reference to a list or a list. If specified the
contents of DATA and a termination string .\r\nis sent to the server. And
the result will be true if the data was accepted.
...

So maybe this'll speed it up a bit? Should go right after
$smtp-to($recipient):

...
open my $msg_fh, '', $outfile
  or die $!, \n;
my @msg_content = $msg_fh;
close $msg_fh;

push @msg_content, \r\n;
$smtp-data(\@msg_content)
  or die 'Sending failed', \n;
...



-- iD

2012/2/23 mailing lists listas.cor...@yahoo.es

 Hello all,


 I have a perl (Ver. 5.10.0) program running over an old machine which send
 messages with this code:


 my $smtp = Net::SMTP-new($dstMailServer, Timeout=10, Debug=0,);
 unless(defined($smtp)){
 syslog LOG_INFO, id:%s error: unable to connect with %s, $myid,
 $dstMailServer;
 exit $EX_TEMPFAIL;
 }
 $smtp-mail($sender);
 $smtp-to($recipient);
 $smtp-data();
 my $line;
 open INPUTFILE, , $outfile or die couldn't open $outfile;
 while(defined($line=INPUTFILE)){
 $smtp-datasend($line);
 }
 close INPUTFILE;
 $smtp-dataend();
 $smtp-quit;


 since the machine belongs to a third party I have no possibility to
 install perl modules (no internet connection, compilers, etc) like Slurp.
 So sending files in the MB range is very slow. Anyone know how to optimize
 (if possible) this code?

 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: Sending files efficiently with Net::SMTP

2012-02-23 Thread Igor Dovgiy
Argh, misunderstood the doc a bit. This line in my code:

push @msg_content, \r\n;

... is redundant, the termination string will be added automatically by
data() method.

-- iD

2012/2/23 Igor Dovgiy ivd.pri...@gmail.com

 From the documentation (http://perldoc.perl.org/Net/SMTP.html)
 ...
 data ( [ DATA ] ) - initiate the sending of the data from the current
 message. DATA may be a reference to a list or a list. If specified the
 contents of DATA and a termination string .\r\nis sent to the server. And
 the result will be true if the data was accepted.
 ...

 So maybe this'll speed it up a bit? Should go right after
 $smtp-to($recipient):

 ...
 open my $msg_fh, '', $outfile
   or die $!, \n;
 my @msg_content = $msg_fh;
 close $msg_fh;

 push @msg_content, \r\n;
 $smtp-data(\@msg_content)
   or die 'Sending failed', \n;
 ...



 -- iD

 2012/2/23 mailing lists listas.cor...@yahoo.es

 Hello all,


 I have a perl (Ver. 5.10.0) program running over an old machine which
 send messages with this code:


 my $smtp = Net::SMTP-new($dstMailServer, Timeout=10, Debug=0,);
 unless(defined($smtp)){
 syslog LOG_INFO, id:%s error: unable to connect with %s, $myid,
 $dstMailServer;
 exit $EX_TEMPFAIL;
 }
 $smtp-mail($sender);
 $smtp-to($recipient);
 $smtp-data();
 my $line;
 open INPUTFILE, , $outfile or die couldn't open $outfile;
 while(defined($line=INPUTFILE)){
 $smtp-datasend($line);
 }
 close INPUTFILE;
 $smtp-dataend();
 $smtp-quit;


 since the machine belongs to a third party I have no possibility to
 install perl modules (no internet connection, compilers, etc) like Slurp.
 So sending files in the MB range is very slow. Anyone know how to optimize
 (if possible) this code?

 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/






Re: perl and pattern

2012-02-22 Thread Igor Dovgiy
What a pleasant thread we've got here. ) Suppose a bit of my ranting won't
spoil it much, will it? ))

2012/2/21 Vyacheslav agapov.sl...@gmail.com


 I'm new in perl and have many questions.

And there's a place to ask them, believe me. )


 This my first programm.

Going straight to the point, I see... Good.

But it'll be even better to start with describing your environment a bit
(version or Perl and platform will surely suffice), and defining your task
as clearly as possible.
In fact, sometimes writing down your task will leave you out of our
pleasant company... )

Let's assume you're working with some kind of built-in Perl, version 5.8,
and your task is as follows: 1) ask your user to enter an integer number,
2) check the input, 3) and print it back only if user followed your rules
and actually entered an integer.

It looks like an easy task - and actually is easy to solve in Perl. )


 my $number = 0;

my $_ = 0;

print Enter number:;

chomp($number = );


Here's a part of your code that solves the first sub-task.
Does it work? Mostly, yes. Can it be improved? Definitely.

First, you don't have to initialize variables in Perl, especially if these
variables are used to store the user input. In fact, it's common to declare
them at the same line where input is collected.

Second, it's a little... optimistic, may I say it, to name an unchecked
variable by its supposed type. ) Doesn't it sound weird to you when you
need to check whether the $number is actually a number, after all? ))

Third, $_ is just that - _special_ Perl variable, waiting there for you at
the first line of Perl code, ready and willing. You don't need to declare
it explicitly - may I say it, EVER. )

So the block we're talking about may be happily rewritten to just:

print Enter a number: ;
chomp (my $user_input = STDIN);

By the way, did you notice the change? ) Only if no arguments were passed
to your program  operator will try to read from STDIN (standard input
stream). But you happen to ask your user for input exactly (remember
'print'?), so I guess STDIN should be processed in every case.

if ( $number = /[0-9]/) ...

 Well, as my colleagues pointed out, what Perl actually sees here is ...if
($number = $_ =~ /[0-9]/)... Perhaps that's why you've tried to initialize
the $_, to get rid of that nasty warning? ) If that's the case, you tried
the wrong remedy: the syntax of checking has to be fixed, not some
declarations.

But here we come back to the first step: unless you define your task
clearly, you won't know what needs to be checked. What is the number YOU
were looking for, after all? ) 3.14 - is it 'number enough' for you? How
about -2.7e10? )

Anyway, if you're looking for integers only, as assumed previously, the
corresponding check should be made of this:
*match the beginning of the line marker, then, optionally, a minus sign,
then any number of digits, then the end of the line marker*, or just
/^-?\d+$/

Finally, about printing the result. It's a matter of taste, but I like to
separate \n symbol from the rest of the line, like this:

print Your number is $user_input, \n;

...or (preferably) just to use 'say' built-in from Perl 5.10, like this:

say You actually entered number $user_input, bless you!;

... as both solutions make the useful content stand more clearly.

#
TL;DR: the core of your program may be rewritten as...

print 'Please, enter an integer number, as I really need it: ';
chomp (my $user_input = STDIN);
if ($user_input =~ /^-?\d+$/) {
  print My hero! You've actually entered $user_input, which is an
integer! I salute you!, \n;
}
else {
  print How dare you insult me with pathetic $user_input!?, \n;
}

Hope this'll be helpful. )

-- iD


Re: perl and pattern

2012-02-22 Thread Igor Dovgiy
...Well, there were no 'only latin number symbols are allowed in user
input' clauses, so \d seems to be more suitable than mere [0-9]. And
for most of my cases \d was sufficient yet shorter than [0-9] - and more
readable, somewhat ironically...

There goes 'why' part. ) And we both, I suppose, may only guess whether or
not /d may be unicode-widened in this case.

But the point is that you're right, and I'm wrong, because the context of
\d (as \w and \s) may be affected by something mildly unrelated to the
containing regex. And that, in my opinion, makes it definitely the bad
thing to teach the beginners. )

So yes, it's safer to go with [0-9]. TIMTOWTDI, of course: using /a
modifier alongside \d-\w-\s. It's even better (as it 'fixes' the context
even for compound regexes, as I understand), but is available only since
5.14.

-- iD

2012/2/22 Dr.Ruud rvtol+use...@isolution.nl

 On 2012-02-22 21:48, Igor Dovgiy wrote:

  Anyway, if you're looking for integers only, as assumed previously, the
 corresponding check should be made of this:
 *match the beginning of the line marker, then, optionally, a minus sign,
 then any number of digits, then the end of the line marker*, or just
 /^-?\d+$/


 Igor, you switched from [0-9] to \d.
 Spoiler: the \d matches 250+ code points.
 Why did you switch?

 --
 Ruud


 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: Keyboard scan codes with Term::Screen

2012-02-20 Thread Igor Dovgiy
Hi Sean,

I don't have Term::Screen installed, but I checked its source - and it
looks like whenever some 'non-function' (i.e., not navigational) key is
pressed, getch() just gives out the corresponding symbol. Perhaps you'd
just check for the spacebar and enter key values (32 and 10, respectively)?

Meanwhile, a bit of advice - if acceptable. ) Whenever you have a really
multiple choice in your code AND you're able to use Perl 5.10 or later, at
least consider using given-when construct instead of if-elsif-else one.

-- iD


2012/2/19 Sean Murphy smur7...@bigpond.net.au

 Hi All.

 I am trying to create my own CLI navigation program. I am using
 Term::Screen since it is nice and simple. I am aware that there are other
 modules out there which does all this. But I want to learn more about the
 navigation of the cursor around the screen. Initially I am working with
 something that I believe is simple and then I will migrate to Curses. But
 not yet.

 I have been successful in creating the menu. The menu wraps. But I cannot
 get the spacebar or enter key to be excepted. Below is the code:


 #!/usr/bin/perl -w

 # Mac Perl 5.12

 use strict;
 require Term::Screen;

  my $scr = new Term::Screen;
  my $win_col = $scr-cols();
 my $win_row = $scr-rows();
 $scr-clrscr();
 $scr-at(0,0)-clreol()-puts (window size: $win_row\t$win_col);

 for (my $r = 2; $r = $win_row; $r++) {
 # prints menu.
my $item = $r -2;
$scr-at($r,10)-puts($item - menu item $item);
 } #end while
 my $curser_char = '_';
 $scr-at(2, 0)-puts($curser_char);
 $scr-noecho();
 my $col = 0;
 my $row = 2;
 my $top_row = 2;
 my $bottom_row = $win_row;

 while ( 1) {
my $key = $scr-getch();
if ($key eq kd) {
$scr-at($row, $col)-puts(' ');
++$row;
$row = $top_row if ($row  $bottom_row);
} elsif ($key eq ku) {
$scr-at($row, $col)-puts(' ');
--$row;
$row = $bottom_row if ($row  $top_row);
} else {
last if ($key eq 'ke');
last if ($key eq 'q');
} #end if
$scr-at($row, $col)-puts($curser_char $row -);
 } # end while

 so how do you capture the Enter or Space?

 I have read the code for Term::Screen and it doesn't appear to have this
 as one of the defined keys in the last routine.

 Sean
 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: looping through an array with for

2012-02-15 Thread Igor Dovgiy
Hi Jim,

Well, instead of asking at each step, whether the last element is processed
or not, it's slightly better to exclude it from the loop:

for my $i (0..$#keyFields - 1) {
  printf %s %s, $keyFields[$i], $match;
}
printf %s %s, $keyFields[-1], $lastmatch;

But yes, I guess your last approach is just what the doctor ordered in this
case. ) I'd use a map, though:

print join ' AND ', map { $_ GE 0 } @keyFields;

.. as, again, it'd be slightly more efficient to allocate the space for the
resulting array just once.

-- iD

2012/2/15 Jim Gibson jimsgib...@gmail.com

 At 9:08 PM -0700 2/14/12, Chris Stinemetz wrote:

 I have a for loop I would like to alter so that when the iteration
 reaches the last element in the array the varibale $lastmatch is
 passed to printf instead of $match.

 Does anyone have any suggestions?

 my $match = GE 0 AND ;
 my $lastmatch = GE 0;

 for my $i (0 .. $#keyFields) {
  printf %s %s, $keyFields[$i], $match,;
 }


 There are several approaches:

 1.


 for my $i (0 .. $#keyFields) {
  printf %s %s, $keyFields[$i], ($i$#keyFields?$match:$**lastmatch);
 }

 2.


 for my $i (0 .. $#keyFields) {
  if( $i == $#keyFields ) {
printf %s %s, $keyFields[$i], $lastmatch;
  }else{
printf %s %s, $keyFields[$i], $match;
  }
 }

 3.

 my @output;
 for my $field (@keyFields) {
  push( @output, sprintf(%s GE O ,$field);
 }
 print join(AND,@output);



 --
 Jim Gibson
 j...@gibson.org


 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: How to process just part of a file

2012-02-09 Thread Igor Dovgiy
First, we should make sure that we can recognize the beginning and the end
of section within CRONDMP file itself.

For example, let's define
my $SEC_START = '## SECTION START',
my $SEC_END = '## SECTION END';

When the source file contains both of these, and so the section we need is
clearly marked, we have two ways of doing the partial processing:
1) either we can redefine an input separator to $SEC_START\n, skip the
first part of file, then cut the resulting string up to $SEC_END, like that:
...
local $/ = $SEC_START . $/;
DATA;
while (DATA) {
  $_ = substr $_, 0, (index $_, $SEC_END);
  my @lines = split /^/;

  ## processing @lines here...

  last;
}
...

2) ...or we can use $in_section flag and control what we do with it:
...
my $in_section;
while (DATA) {
  if ($in_section) {
last if /$SEC_END/;
### insert original code here
  }
  else {
$in_section++ if /$SEC_START/;
  }
}
...

Each way has its advantages and disadvantages, as usual.  )

-- iD

2012/2/9 Clay Lovett clay.lov...@carquest.com

 I have inherited a script that processes the cron and comments stuff out
 for month end processing. We have added some store that do not run the same
 monthly calendar as the rest of the stores. What I need to know is how to
 add a start and a finish section to the code so that it only processes the
 section I want it to. I have included the code below:

 while(CRONDMP){
s/\n|\r//g;

$PoutputFile5pm=
(/icpw/  /start_pricingfeed.sh/) ||
(/icpw/  /start_inventoryfeed.sh/) ||
(/icpw/  /start_customerfeed.sh/) ||
(/DwInventoryFeed/  /dw_inventory_feed.pl/) ||
(/CustFeed/  /XplCust.sh/) ||
(/CustFeed/  /accUpd.sh/) ||
(/RebateFileExtract/  /rebate_file_extract.pl/)
;

$PoutputFile915pm=
(/icpw/  /start_pricingfeed.sh/) ||
(/icpw/  /start_inventoryfeed.sh/) ||
(/icpw/  /start_customerfeed.sh/) ||
(/DwInventoryFeed/  /dw_inventory_feed.pl/) ||
(/CustFeed/  /XplCust.sh/) ||
(/CustFeed/  /accUpd.sh/) ||
(/RebateFileExtract/  /rebate_file_extract.pl/)
;

if($PoutputFile5pm){
print CRON5PM ###cmt###$_\n;
}else{
print CRON5PM $_\n;
}

if($PoutputFile915pm){
print CRON915PM ###cmt###$_\n;
}else{
print CRON915PM $_\n;
}


print CRONORIG $_\n;
 }

 Thanks in advance

 Clay Lovett, MBA/TM
 UNIX Systems Administrator
 GPI Technologies, LLC


 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: Editing line of text.

2012-02-08 Thread Igor Dovgiy
Hi Sean,

Let's follow the documentation, shall we? )

-- readline(PROMPT[,PREPUT])
Gets an input line, with actual GNU Readline support. Trailing newline is
removed. Returns undef on EOF.
PREPUT is an optional argument meaning the initial value of input.
The optional argument PREPUT is granted only if the value preput is
in Features.

It's easy to check that Term::ReadLine::Stub (used as implementing module
by default, it seems) doesn't support preput feature. Just check
$rl-Features.
But Term::ReadLine::Gnu does, as it's an interface to a very
powerful {libreadline} term library.

So install Term::ReadLine::Gnu module (if needed, libreadline-dev as well)
- and have fun with preput text without changing a line in Shlomi code. )

-- iD

2012/2/8 Sean Murphy mhysnm1...@gmail.com

 Hi Shlomi

 I used your example code and the 'hello' did not appear on the input
 field. The '$' did as the prompt. So I couldn't edit the 'hello'. I had to
 enter it in. Below is the example output:

 Output:

 $ typed in 'hello'
 You've given 'hello'
 $

 What I wanted was:

 $Hello
 You've given 'hell'
 $

 As you can tell the 'hello' is shown. I want to delete a single character
 in the above example to get Hell. The code I used was:


 #!/usr/bin/perl -w

 # test readline.


 use strict;
 use warnings;

 use Term::ReadLine;

 my $rl = Term::ReadLine-new ('test');

 while (my $text = $rl-readline('$', 'Hello'))
 {
   print You've given '$text'\n;
 }

 So it appears the line in the while ignores the 'hello' parameter.

 Thanks for the code. Any other ideas?

 Sean
 On 08/02/2012, at 7:01 PM, Shlomi Fish wrote:

  Hi Sean,
 
  On Wed, 8 Feb 2012 18:37:37 +1100
  Sean Murphy mhysnm1...@gmail.com wrote:
 
  Hi All.
 
  This should be a simple task. But for the life of me, I cannot work it
 out.
  I have a chunk of text in an scaler. I want to edit this text. I look
 at Term::ReadLine and couldn't see a way of inserting the text into the
 edit area. There is addhistory  which adds to the history buffer. but this
 isn't want I want.
 
  For example:
 
  $text = this is a test;
  $text = function ($text); # permits full editing of line.
  print $text\n;
 
  When script is executed. The text in $text is displayed. The cursor and
 delete commands work. So the line can be modified.
 
  so how can this be done? I haven't seen any modules that seem to permit
 this. Example code would be great.
 
  This is for a program I am writing to handle my home budgets. I am
 extracting the text from a database using DBI.
 
 
  After reading https://metacpan.org/module/Term::ReadLine::Gnu I came up
 with
  the following program which appears to start with the string Hello.
 Hope it
  helps:
 
  #!/usr/bin/perl
 
  use strict;
  use warnings;
 
  use Term::ReadLine;
 
  my $rl = Term::ReadLine-new;
 
  while (my $text = $rl-readline('$', 'Hello'))
  {
 print You've given '$text'\n;
  }
 
  =
 
  Regards,
 
Shlomi Fish
 
 
  Sean
 
 
 
  --
  -
  Shlomi Fish   http://www.shlomifish.org/
  Free (Creative Commons) Music Downloads, Reviews and more -
 http://jamendo.com/
 
  And the top story for today: wives live longer than husbands because
 they are
  not married to women.
 — Colin Mochrie in Who’s Line is it, Anyway?
 
  Please reply to list if it's a mailing list post - http://shlom.in/reply.


 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: How to Digest::CMAC-add($json)

2012-02-07 Thread Igor Dovgiy
It's not an encoding issue. It's a 'storage' issue. )

JSON::to_json returns a string, with UTF8 flag on.
JSON::encode_json returns a bytecode (sequence of octets), with UTF8 flag
off.

-- iD

2012/2/7 John Refior jref...@gmail.com

 On Mon, Feb 6, 2012 at 11:21 PM, John Refior jref...@gmail.com wrote:

  I am trying to create a CMAC out of some JSON data (I have a reason for
  doing this -- part of the authorization allowing my REST client to
  communicate with a server that requires it).  I figured I would use
  Digest::CMAC to do this (but if someone knows a better way, please let me
  know).  However, I'm trying to create the CMAC out of JSON data, and I'm
  getting an error.  I wrote a little test script to demonstrate, here's
 the
  code:


 

  I added the Crypt::Rijndael-encrypt at the end just to see if that would
 work on the bare JSON string, and it does.  Here's the output of the
 script:

 
  OUTPUT
  $json is: {three:3,five:5,one:1,two:2,four:4}
  Attempting to Digest::CMAC-add($json)
  [eval error]: encrypt: datasize not multiple of blocksize (16 bytes) at
  /export/home/apps/public/lib/perl5/site_perl/5.10.0/Digest/OMAC/Base.pm
  line 56.
 
 
 
  Crypt::Rijndael-encrypt(\$json): G`'/Mβ©Y¦¾Ï)=ôÎlÛÝf?´²­lÕeyûÊ¡í
  /OUTPUT
 
  If not for the eval, the script would stop execution at that error.
   The Crypt::Rijndael-encrypt call on the bare JSON does not cause an
 error.
 
  Does anyone have a suggestion for how I can create a CMAC using a JSON
  string?
 

 Thought I would write again to say that it appears I've fixed this problem
 by switching from JSON::to_json to encode_json.  I haven't yet figured out
 why this makes a difference (encoding issue? feel free to chime in if you
 have an idea), but it appears it does.

 Thanks,

 John



Re: need guidance on encode JSON and sorting

2012-02-06 Thread Igor Dovgiy
That's what the documentation says:
...
$json = $json-canonical([$enable])
If $enable is true (or missing), then the encode method will output JSON
objects by sorting their keys. This is adding a comparatively high
overhead.
...

So I guess you'd have to use something like that:

my $ret_json = JSON::XS-new-canonical()-encode($tmp_hash);

-- iD

2012/2/6 Rajeev Prasad rp.ne...@yahoo.com

 i changed and not getting error anymore but the list is still not
 sorted.


 my $json = JSON::XS-new;
 $json-get_canonical;
 $return_json_text = $json-encode ($tmp_hash);
 ---no error, but does not produce sorted output


 the key is a datetime field e.g.: 2012-01-20 22:24:36   value is some
 text




 - Original Message -
 From: Rajeev Prasad rp.ne...@yahoo.com
 To: perl list beginners@perl.org
 Cc:
 Sent: Sunday, February 5, 2012 10:20 PM
 Subject: Re: need guidance on encode JSON and sorting

 I tried below but getting err:

 my $json = JSON::XS-new;
 $json-get_canonical;
 $return_json_text = $json-encode $tmp_hash;

 Scalar found where operator expected atscript.pl line 80, near -encode
 $tmp_hash


 ???




 - Original Message -
 From: Rajeev Prasad rp.ne...@yahoo.com
 To: perl list beginners@perl.org
 Cc:
 Sent: Sunday, February 5, 2012 10:04 PM
 Subject: need guidance on encode JSON and sorting

 in the script this is all i am using JSON as:

 ...
 use JSON::XS;
 ...
 
 $return_json_text = encode_json $tmp_hash;

 this variable ($return_json_text) is then used to display values. I need
 this to be orderd, but not able to figure how to order the outcome??? I
 read about $enabled = $json-get_canonical on JSON's page but not sure hot
 use it as i do not have $json or such object created. Also I am assuming it
 would be sorted on key field of the JSON hash.

 ty.
 Rajeev

 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/


 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: Parsing Question

2012-02-01 Thread Igor Dovgiy
Just my $0.02... can't help offering a slight rewrite of David's great
program.
Now it's runnable on 5.010 and earlier, and should give out some warnings
if hoststatus sections are somehow corrupt:

$|++; # comment it out if you don't need to buffer the output
my $section_started;
my ($host, $state);
while(DATA) {
if ($section_started) {
$host = $1, next if /host_name=(\w+)/;
$state = $1, next if /current_state=(\d+)/;
if (/^\s*}\s*$/) {
print defined $host  defined $state
? $host:$state\n
: Invalid section started at $section_started\n;
$section_started = 0;
}
}
else {
$section_started = $., ($host, $state) = () if /hoststatus\s*{/;
}
}

-- iD

2012/2/1 Brandon Phelps bphe...@gls.com

 Thanks a ton David,

 This will definitely help!  Not able to try it now but I'll give it a shot
 first thing tomorrow.

 -Brandon

 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: Dereferencing an array

2012-01-27 Thread Igor Dovgiy
Hi Rob,

Just'd like to add my $0.02 to the brilliant solutions you offered. )

You can access the anonymous arrays from @desc using

  foreach my $rest (@desc) {
print @$rest\n;
  }

 Or just...
  say @$_ for @desc;
... if one prefers conciseness - and is able to use 5.010, of course. )

But there is no need to split the thrid field in the first place.

Even more, it may produce slightly incorrect results: blocks of whitespace
in @rest will collapse into single space when quote-printed (print
@rest). Tabulations will be reduced to a simple space symbol as well.


 You have two options: first to split on more than a single space with
 my ( $lat, $lon, $rest ) = split /\s{2,}/;

This solution will work correctly only if 'remainder' part of phrase won't
have spacings longer than 1 symbol. Otherwise the rest of phrase will be
omitted - without any warnings whatsoever.

and secondly to limit the number of fields that split() divides the record
 into
  my ( $lat, $lon, $rest ) = split ' ', $_, 3;

And this solution will work correctly all the time, which (in my opinion)
makes it preferable. ) Besides, it should work a bit faster.

Be aware that both of these techniques will leave the newline on the end
 of the last field, so a call to chomp() will be necessary as the first
 line of the while loop.

Or then again, we may just chomp the $rest if necessary.

-- iD


Re: Collecting variables from Hash

2012-01-23 Thread Igor Dovgiy
Hi Pradeep,

use List::Util qw( sum );
use constant {
  SUFFICIENT_SUCCESS = 244
}
...
my $success = sum( map { /success$/ ? $results_href-{$_} : () } keys
%$results_href );
...
return $success ==  SUFFICIENT_SUCCESS;

-- iD

2012/1/22 Pradeep Patra smilesonisa...@gmail.com

 Hi,
   I have a hash reference as follows:

 $VAR1 = {
A.processor0.error   = 0
A.processor0.success = 77
A.processor0.total= 77
A.processor1.error= 0
A.processor1.success  = 57
A.processor1.total= 57
A.processor2.error= 0
A.processor2.success  = 110
A.processor2.total= 110



 }


 I want to collect the values from the different processors(for exp:
 success value of processor0,processor1,processor2 and sum them i.e 77
 + 57 +110 = 244 ).and store in a variable $success.

 If ($success == 244)
 {
return 1;



 } else {
 return 0;
 }


 Can anybody help me in this regard?

 Regards
 Pradeep



 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: Difference between and grep EXPR,

2012-01-20 Thread Igor Dovgiy
2012/1/20 Andrey P andrey.y...@gmail.com

 Hi!
 I don't understand why I need to use a list assignment for
say  scalar(()=$fh);
 but not for
say  scalar(grep /./, $fh);


Because grep gives a list context to its second operand, just like the nuke
( ()= ) operator does. )
Remember, a context is what's wanted, not what's given. )

-- iD


Re: How to merge multiple array elements

2012-01-16 Thread Igor Dovgiy
2012/1/15 Pradeep Patra smilesonisa...@gmail.com

   I want to merge more than 2 arrays.

 @array = (@array1,@array2,@array3,@array4);
  print Array elements:@array;

 It works and displays 1-12. But I need something different because i
 dont know the value of n beforehand.

What do you mean by 'n'?
Size of the final array? It's { scalar @final_array }, yes, that simple. )

Number of arrays to merge? Well, I guess they should be stored somewhere
anyhow. )
And if they're stored in some collection, like...
*my @collection_of_arrays = (*
*  [1, 2, 3],*
*  [4, 5, 6],*
*  [7, 8, 9] *
*)*
... then again the number is the size of this collection. And it's pretty
easy to flatten this @collection, like this:
*my @flattened_collection = map { @$_ } @collection_of_arrays;*
*
*
You'd like to store arrays as separate variables instead - but don't know
their number at 'compilation' time? ) And this is practical task? )
Yes, this can be solved with soft references one way or another (*@result_array
= map { eval { '@array'.$_ } } 1..n*), but why you might ever need this, is
beyond me. )
*
*
-- iD


Re: base64 to hex conversion

2012-01-16 Thread Igor Dovgiy
Hi Ramprasad,

Perhaps...
*use MIME::Base64 qw/decode_base64/;*
*...*
*my $res = unpack('H*', decode_base64($source));*
...will do the trick? )

-- iD

2012/1/16 Ramprasad Prasad ramprasad...@gmail.com

 Hello

 what is the best way to convert base64 to hex

 I am currently using




Re: Appending extra characters to file name

2012-01-05 Thread Igor Dovgiy
Hi Alex,

Your script should be like that:

$oldfile = $file;
chomp($oldfile);
my $newfile = $oldfile . .x;

... as $file (and $oldfile, which is redundant btw) ends with \n.

Besides, it'd be much easier to collect all the files in the given
directory with fileglob.

-- iD


2012/1/5 Alex Ardin alexardi...@gmail.com

 Hi,
 I frequently have to review logs that are captured with 'script' using
 terminal but these logs have many control characters.

 The intent of the script is the following:

 1. Get a listing of all the logs in a directory, storing the list of
 files in an array.
 2. For each filename in the array, create a new filename but append a
 .x to the original filename, so that file 'a' would result in a new
 file 'a.x', as an example.
 3. Open the original file, search and remove any control characters
 (such as  ^M, ^C, and so on) line by line and store the results in the
 newly created file ending in .x (such as the a.x example above).
 4. After reaching the end file, close both files.
 5. Move the newly created .x file so that it replaces the original
 file (or 'mv a.x a' in the example above).

 What happens is that the script works fine, all control characters are
 replaced in the file, but the move fails, so that if I start with a
 directory containing these files:

 xong$ ls -rlt
 -rw-r--r--  1 rootroot  staff  50033 Oct 11 17:43 xyz
 -rw-r--r--  1 rootroot  staff  50033 Oct 13 18:57 123

 when the script finishes executing, I end up with these file, the
 first two are the original files with all the control characters, the
 last two are the newly created files with the control characters
 removed:

 xong$ ls -rlt
 -rw-r--r--  1 rootroot  staff  50033 Oct 11 17:43 xyz
 -rw-r--r--  1 rootroot  staff  50033 Oct 13 18:57 123
 -rw-r--r--  1 rootroot  staff  49792 Jan  4 22:14 xyz?.x
 -rw-r--r--  1 rootroot  staff  49792 Jan  4 22:14 123?.x

 Here's the errors I see when the script executes, the comments are
 just for debugging:

 Here's a listing of the files:
 123
 xyz

 Here's newfile: 123
 .xHere's oldfile: 123

 Now mv file
 Here's newfile: 123
 .xHere's oldfile: 123
 usage: mv [-f | -i | -n] [-v] source target
   mv [-f | -i | -n] [-v] source ... directory
 sh: line 1: .x: command not found

 I'm not sure why this is happening, the newfile should contain 123.x
 but instead the .x is appearing on the newline.  I've gone through the
 Programming Perl book and can't seem to fine another way to do this,
 and I've also searched this group, and didn't find anything similar.

 Here's the script:

 #!/usr/bin/perl

 #
 # Delete all control characters in a group of files in a directory.
 #

 #use strict;
 use warnings;

 if ($#ARGV != 0) {
print \nusage: get_file_list.pl directory\n\n;
exit;
 }

 $dir_path = $ARGV[0];
 chdir $dir_path or die \ncd failed, check file path!\n\n;

 $cmd = pwd;
 if(system($cmd)) { print \n\npwd failed.\n; }

 $cmd = ls -l;
 if(system($cmd)) { print \n\nFile listing failed.\n; }

 # Store file listing in a array:
 $cmd = ls;
 my @fl = qx($cmd);

 print \nHere's a listing of the files:\n;

 foreach $file (@fl) {
print $file;
 }

 I thought it was a result of my foreach loop but the loop exits after
 the last file is reached, so there's nothing to force a newline when
 my script copies the original filename to a new file name ending in
 .x.

 foreach $file (@fl) {
$oldfile = $file;
my $newfile = $oldfile . .x;
print(Here's newfile: $newfile);
print(Here's oldfile: $oldfile);

open(OF, $oldfile);
open(NF, $newfile);

# read in each line of the file
while ($line = OF) {
$line =~ s/\cM//g;
$line =~ s/\cH//g;
$line =~ s/\cC//g;
$line =~ s/\cL//g;
$line =~ s/\cG//g;
$line =~ s/\cP//g;
$line =~ s/\cQ//g;
$line =~ s/\cR//g;
$line =~ s/\c[//g;
print NF $line;
}

print(\nNow mv file\n);
print(Here's newfile2: $newfile);
print(Here's oldfile2: $oldfile);

$cmd = mv $newfile $oldfile;
if(system($cmd)) { print rename failed\n; }

close(OF);
close(NF);
 }

 I also thought it had been the result of my closing my files after I
 attempted the move, but I get the same results if I move these lines:

close(OF);
close(NF);

 above this line:

 print(\nNow mv file\n);

 so that the files are closed and then attempt to move them.

 Is it possible to understand how to work around this?

 Alex


 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: File Size Script Help - Working Version

2012-01-03 Thread Igor Dovgiy
Hi folks, happy new year to everyone. )

John, you're right, of course. ) The filenames in nested directories could
well overlap, and using $File::Find::name would be safer.
Didn't think of that as a big problem, though, as original script (with
'opendir') ignored all the nested folders overall.

Jonathan, no, you don't have to store the filenames as array: complete
pathnames of the file can't be repeated.
It'll be sufficient just to change this line:
$filedata{$_} = [$filesize, $filemd5]
for
$filedata{$File::Find::name} = [$filesize, $filemd5]

(and replace catfile in the writing block as well, as %filedata keys will
now be the whole filenames themselves).

On sorting: cmp and = is not the same: former compares strings, latter -
numbers.
So, for example, 'abc' cmp 'def' gives you -1, but 'abc' = 'def' gives 0
(and warnings about non-numeric args as well).

It's nice to know the difference, but... do you really need to sort the
output in your script? What output? )
It makes no difference in what order your .md5 files will be created,
right? And you don't need to print the list of files processed
(as I did in my test script, that's why the ordering was ever mentioned).

As for $_, the problem John mentioned is logical, not 'perlical': as $_
variable is assigned a filename processed within File::Find target sub,
and files in different directories could have the same names (but not full
names, with absolute path attached), it may cause a bit of confusion when
they DO have the same names. )

Generally speaking, $_ usage is for comfort and speed (yes, thinking of it
as of 'it' word is right )). Of course, you can reassign it, but it'll make
your scripts bigger (sometimes _much_ bigger) without adding much clarity,
in my opinion. But that, again, is a matter of taste.

For me, I use $_ almost every time I process shallow collections (hashes or
arrays, doesn't matter). When two-level (or more complex) data structure is
processed, it's usually required to use a temporary variable - but even
then inner layers can be iterated with $_ easily.

-- iD


Re: File Size Script Help - Working Version

2011-12-30 Thread Igor Dovgiy
Hi Jonathan,

Argh, really stupid mistake by me. ) But let's use it to explain some
points a bit further, shall we?
A skilled craftsman knows his tools well, and Perl programmer (with CPAN as
THE collection of tools of all sizes and meanings) has an advantage here: even
if documentation is a bit vague about what's going on, we are (usually)
able to check the code itself to find the answers. )

By browsing File::Spec source (found via 'Source' link within the
'File::Spec' page at CPAN)...
http://cpansearch.perl.org/src/SMUELLER/PathTools-3.33/lib/File/Spec.pm
...we soon discover that this module is essentially an adapter for modules
like File::Spec::Unix, File::Spec::Mac, File::Spec::Win32 etc.
So our search goes on (as your mention of .DS_Store file implies) over
there:
http://cpansearch.perl.org/src/SMUELLER/PathTools-3.33/lib/File/Spec/Mac.pm

Now we may either check the documentation (which clearly states that only
the last argument to catfile is considered a filename, and all the others
will be concatenated with catdir), or look right into the code - and come
to the same conclusion:

sub catfile {
my $self = shift;
return '' unless @_;
my $file = pop @_;
return $file unless @_;
my $dir = $self-catdir(@_);
$file =~ s/^://s;
return $dir.$file;
}

So what should we do now? ) Of course, give milk to our cat... and
arguments to File::Spec's catfile! ) Like this:

File::Spec-catfile($path, $dircontents . '.md5')
... or this...
File::Spec-catfile($path, $dircontents.md5)
(check 'variable interpolation in Perl' to see why it's possible - and why
this is essentially the same as previous codeline)
... or even this ...
File::Spec-catfile($path, join '.', $dircontents, 'md5')
(but that would be a bit overkill, of course :)

Speaking of overkills: you used regex (=~ /^\./) to check whether the line
begins with a dot - or not. )
It's ok for this task, but you probably should know that these checks may
be also done with (substr($line, 0, 1) eq '.') code,
which will be a bit (up to 30% at my PC when Benchmark'ed) faster.

-- iD

2011/12/30 Jonathan Harris jtnhar...@googlemail.com

 I tried to use your suggestion
 open my $wr_fh, '', File::Spec-catfile($path, $dircontents, '.md5') or
 die $!, $/
 but it returned an error on the command line:
  'Not a directory'
  At which point the program dies (which is what it is supposed to do!)
  I used it inside the loop - sorry to bug you for clarification


 
 if ($dircontents=~/^\./ || -d $dircontents) {
  next;
 }

 This is also to avoid the file .DS_Store




Re: File Size Script Help - Working Version

2011-12-30 Thread Igor Dovgiy
Hi John, yes, good point! Totally forgot this. ) Adding new files to a
directory as you browse it is just not right, of course. Possible, but not
right. )

I'd solve this by using hash with filenames as keys and collected 'result'
strings (with md5 and filesizes) as values, filled by File::Find target
routine.
After the whole directory is processed, this hash should be 'written out'
into the target directory.

Another way to do it is to collect all the filenames instead into a list
(with glob operator, for example), and process this list after.

BTW (to Jonathan), I wonder do you really need to store this kind of data
in different files? No offence... but I can hardly imagine how this data
will be used later unless gathered into some array or hash. )

-- iD

2011/12/30 John W. Krahn jwkr...@shaw.ca

 Jonathan Harris wrote:


  Hi John

 Thanks for your 2 cents

 I hadn't considered that the module wouldn't be portable


 That is not what I was implying.  I was saying that when you add new files
 to a directory that you are traversing you _may_ get irregular results.  It
 depends on how your operating system updates directory entries.




Re: What does = means?

2011-12-30 Thread Igor Dovgiy
Hi Xi,

You're looking only for 'p' letters, not D and O? Why?

Anyway, generic solution will be something like...

my %seen;
my @repeated = grep { /some regex here/  $seen{$_}  N }  @source_array;

... where N is how many times the symbols should appear in the source array
to be counted as duplicate.
and 'some regex' is, well, some regex to filter the symbols if needed. :)

-- iD

2011/12/30 Xi Chen cxde...@gmail.com

 Yes, I agree the code looks strange. Do you have any idea to do this
 with a clear code? I mean to find two same letters, p in @a?

 Xi

 On Thu, Dec 29, 2011 at 10:17 PM, John W. Krahn jwkr...@shaw.ca wrote:
  Xi Chen wrote:
 
  Hello everyone,
 
  I saw a code below to get two same letters p in @a.
 
  @a = qw (D D p O H p A O);
  foreach $b (@a){
  $n =~ /$b/i;
  if($n= 2){
   $m = $b;
  }
  }
 
  But I don't know what does = mean. Thank you!
 
 
  It means greater than or equal to.  The expression $n = 2 is true if
  the value in $n is equal to 2 or is any value greater than 2, 6 for
 example.
   If the value in $n is less than 2 then the expression is false.
 
  Your algorithm looks weird though because you are testing $n for the
  presence of alphabetic characters (and then not using that information)
 and
  then using $n in a numerical context.
 
 
 
  John
  --
  Any intelligent fool can make things bigger and
  more complex... It takes a touch of genius -
  and a lot of courage to move in the opposite
  direction.   -- Albert Einstein
 
  --
  To unsubscribe, e-mail: beginners-unsubscr...@perl.org
  For additional commands, e-mail: beginners-h...@perl.org
  http://learn.perl.org/
 
 

 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: What does = means?

2011-12-30 Thread Igor Dovgiy
Oh my, of course it should be...
my @repeated = grep { /some regex here/  ++$seen{$_}  N }  @source_array;
... to work properly.

-- iD

2011/12/30 Igor Dovgiy ivd.pri...@gmail.com

 Hi Xi,

 You're looking only for 'p' letters, not D and O? Why?

 Anyway, generic solution will be something like...

 my %seen;
 my @repeated = grep { /some regex here/  $seen{$_}  N }  @source_array;

 ... where N is how many times the symbols should appear in the source
 array to be counted as duplicate.
 and 'some regex' is, well, some regex to filter the symbols if needed. :)

 -- iD

 2011/12/30 Xi Chen cxde...@gmail.com

 Yes, I agree the code looks strange. Do you have any idea to do this
 with a clear code? I mean to find two same letters, p in @a?

 Xi

 On Thu, Dec 29, 2011 at 10:17 PM, John W. Krahn jwkr...@shaw.ca wrote:
  Xi Chen wrote:
 
  Hello everyone,
 
  I saw a code below to get two same letters p in @a.
 
  @a = qw (D D p O H p A O);
  foreach $b (@a){
  $n =~ /$b/i;
  if($n= 2){
   $m = $b;
  }
  }
 
  But I don't know what does = mean. Thank you!
 
 
  It means greater than or equal to.  The expression $n = 2 is true
 if
  the value in $n is equal to 2 or is any value greater than 2, 6 for
 example.
   If the value in $n is less than 2 then the expression is false.
 
  Your algorithm looks weird though because you are testing $n for the
  presence of alphabetic characters (and then not using that information)
 and
  then using $n in a numerical context.
 
 
 
  John
  --
  Any intelligent fool can make things bigger and
  more complex... It takes a touch of genius -
  and a lot of courage to move in the opposite
  direction.   -- Albert Einstein
 
  --
  To unsubscribe, e-mail: beginners-unsubscr...@perl.org
  For additional commands, e-mail: beginners-h...@perl.org
  http://learn.perl.org/
 
 

 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/






Re: problem with passing variables

2011-12-30 Thread Igor Dovgiy
Hi Mark,

If your variables are strictly internal and by no means might be ever
tainted (read: user input), what you're doing is mostly ok.
But you need to quote the dates passed within query itself, like this:

my $sql = qq/SELECT * FROM `events` WHERE `date` BETWEEN '$begin_time' AND
'$end_time'/;
*(qq, of course, not q: you'd like your variables to be interpolated, would
you? :)*

But there's another (and in my opinion, usually better) way: using prepared
sql statement:
my $sth = $dbh-prepare(q/
  SELECT * FROM `events` WHERE `date` BETWEEN ? AND ?
/);
$sth-execute($begin_time, $end_time);

This method is safer, but a little (or not, depending on driver and DB
used) bit slower than direct queries.

Have to say that I usually prefer even simpler DBI methods, like
selectall_arrayref, combining the power of `prepare`, `execute` and `fetch`
methods in one statement. But that's a matter of taste, I guess. )

-- iD

P.S. BTW, if you want to know the reason why particular SQL query fails,
just call errstr method of your DBI object (like $dbh-errstr) - and print
the result. )

2011/12/30 Mark Haney ma...@abemblem.com

 I'm not sure if this is the right list for this, so bear with me.  If it
 isn't I'll be glad to post it on the correct one.

 I've got a problem with passing variables to a SQL server inside a CGI
 script.  My code is like this:

 my $begin_time = 2011-11-16 11:00:00;
 my $end_time = 2011-11-16 12:00:00;

 my $dbh = DBI-connect('dbi:mysql:**database=embdev', 'user', 'password');

 my $sql = q/SELECT * FROM events WHERE date BETWEEN $begin_time and
 $end_time/;

 my $sth = $dbh-prepare($sql);
 $sth-execute();

 I'm not sure why it's not using the the variables, can someone point out
 what I'm doing wrong?

 -
 Mark Haney


 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: problem with passing variables

2011-12-30 Thread Igor Dovgiy
If you pass into SQL query something assigned by user, use placeholders by
all means. ) It's not that hard, but it'll save you a lot of headaches,
believe me. )

2011/12/30 Mark Haney ma...@abemblem.com

 But there's another (and in my opinion, usually better) way: using
 prepared sql statement:
 my $sth = $dbh-prepare(q/
   SELECT * FROM `events` WHERE `date` BETWEEN ? AND ?
 /);
 $sth-execute($begin_time, $end_time);


 I can certainly do it this way, however, my ultimate goal is to have these
 variables passed via a web form and since I'm still getting my feet wet
 with using perl to a MySQL database exclusively (I can do SQL very well,
 but never inside perl) I am taking baby steps.




Re: File Size Script Help - Working Version

2011-12-30 Thread Igor Dovgiy
Great work, Jonathan!
Notice how simple your script has become - and that's a good sign as well
in Perl. :) We can make it even simpler, however.

As you probably know, Perl has two fundamental types of collections: arrays
(where data is stored as a sequence of elements, data chunks) and hashes
(where data chunks are unordered, but stored with some unique key used to
retrieve it). Sometimes hashes are used just to sort out (non-)unique data,
but that's another story.

Now look at this line:
   push @{$files{$filesize}}, $File::Find::name;

Don't you see something... weird? You're using hash where filesizes are the
keys - and because, yes, they may well be non-unique, you have to store
arrays of filenames in your hash instead...

But much more natural (at least, for me) is to organize your hash (let's
call it %filedata) so that filenames (which are unique by their nature)
become the keys. And some info about these files - sizes and md5-hashes -
become the values.

For example, our `wanted` (btw, its name is misleading a bit, no? may be
'process' will sound better?) sub may look as follows:

find(\wanted, $path);

my %filedata;
sub wanted {
  return if substr($_, 0, 1) eq '.' || -d $_;
  my $filesize = -s _;
  open my $fh, '', $_ or die $!, $/;
  my $filemd5 = Digest::MD5-new-addfile($fh)-hexdigest;
  close $fh;
  $filedata{$_} = [$filesize, $filemd5];
}

(*Notice how you don't have to declare the global filedata hash before the
callback function is called in `find`? It's really interesting topic*)

Then you'll just have to iterate over the %filedata - and it's as easy as
writing...

for my $filename (keys %filedata) {
  my ($size, $md5) = @{ $filedata{$filename} };
  open my $fh, '', File::Spec-catfile($path, $filename.md5)
or die $!, $/;
  print $fh $filename\t$size bytes\t$md5\n;
  close $fh;
}

... yep, that easy. )

-- iD

P.S. Ordering the output should be an easy task for you; hint - look up
'sort' documentation - or just use sort system routine. :)

2011/12/31 Jonathan Harris jtnhar...@googlemail.com

 HI Brandon

 Thanks for your response


 I totally agree with your first point
 Having now used File::Find a little more, I have seen that using opendir
 was totally unneccessary and have removed them from the script
 And guess what.it works fine without them!
 I think that my initial confusion arose from fundamentally misunderstanding
 File::Find - thinking that it required a handle, not just a path.

 I have also now exchanged the while loop with a foreach loop - much better!

  I assume you meant `hexdigest' here, not 'hex digest'.

 You assume correctly! Gmail has started to do annoying auto text complete -
 I must turn it off!!

  push @files, $File::Find::name if -f $_;

 This is nice and clean

 Your approach is different to what we have been discussing
 You seem to gather the files with File::Find and then leave that sub alone
 asap
 The processing is then done in the results of that gathering

 My script left the processing within sub wanted
 This could possible be a reason that complications arose so quickly

 To get file names and sizes at the same time, I am also considering

 my %files;

 sub wanted {
my $filesize = (stat($_))[7];
push @{$files{$filesize}}, $File::Find::name;
 }

 find(\wanted, $path);

 to hash files and file size results together - then process after

 And yep, Igor has been thorough and very helpful

 Thanks again for your input on this - hope you manage to get some sleep!

 All the best

 Jonathan



Re: File Size Script Help - Working Version

2011-12-29 Thread Igor Dovgiy
Hi Jonathan,

Let's review your script a bit, shall we? )
It's definitely good for a starter, but still has some rough places.

#!/usr/bin/perl
 # md5-test.plx
 use warnings;
 use strict;

use File::Find;

use Digest::MD5;
 use File::Spec;

So far, so good. )


 my $dir = shift || '/Users/jonharris/Documents/begperl';

Nice touch, setting up a default param. ) The name of variable might seem
too generic to some, but then again, it's the only directory we deal with,
so...


 my ($dircontents, $path, @directory, $fh, $wr_fh);

Incoming!

Well, it's usually better to declare your variables right before you'll
really need them...
Your script is short, so you'll hardly have a chance to forget what $fh and
$wr_fh mean, though. )


 @directory = $dir;
 $path = File::Spec-catfile( @directory, $dircontents );

Ahem. At least three 'wtf' moments for me. )
First of all, File::Spec-catfile is really just a glorified join operator
with some additional operations depending on which system you're using.
So, second, it makes a little sense to convert $dir into @directory
(documentation example is just that, an example) and to pass there
undefined $dircontents as well.
But the major one is why you'd ever have to pass your $dir through
File::Spec? It's, you know, user input... )

opendir (my $in, $path) or die Cannot open $dir: $!\n;

So you're trying to open $path, but warn about failure to open $dir? )
But then again, that's a minor quarrel, considering this:


 find (\wanted, $path);

See, File::Find is convenient method which _emulates_ the whole
opendir-readdir-closedir pattern for a given directory.
The 'wanted' subroutine (passed by ref) will be called for each file found
in $path.
It's described really well in perldoc (perldoc File::Find).

close $in;

Opendir, but close - and not closedir? Now I'm confused. )

opendir (my $totalin, $path) or die Cannot open $dir: $!\n;
 find (\cleanup, $path);
 close $totalin;

You don't have to use different variable to store temporary file handle
(which will be closed in three lines) - and that will save you a few
moments spent working out a new (but rational) name for it. :)
But then again, you don't need to open the same dir twice: you can call
cleanup (with the same 'find (\cleanup)... ' syntax) whenever you want.
And you don't really need cleanup... whoops, going too far too soon. :)

print \n\nAll Done!\n\n;


 sub wanted {
 while ($dircontents = readdir($in)) {

Did I say that you're using two alternative methods of doing the same
thing? )
But there's another big 'no-no' here: you're using external variable
($dircontents) when you really have perfectly zero reasons to do so.
Of course, you don't need to push dirhandle ($in) from outer scape into
this sub, when using find... ($File::Find::dir will do), but that's
explainable at least. )

 if ($dircontents=~/^\./ || -d $dircontents) {
 next;
 }

So now the script ignores all the files which names begin with '.', and you
really wanted just to ignore '.' and '..' ... )

my $bytes = -s $dircontents;

print $dircontents, \n;
 print $bytes,  bytes, \tSo far so good!\n;

Yes. )

  open $fh, , $dircontents or die $!;
 open $wr_fh, +, $path $dircontents.md5 or die $!;  ## was unable to
 concatenate here, hence sub cleanup to remove the ' '

What was wrong with ...
open my $wr_fh, '', File::Spec-catfile($path, $dircontents, '.md5') or
die $!, $/
?


 my $hex = Digest::MD5-new-addfile($fh)-hex digest;
 print Hex Digest: , $hex, \n\n;
  print $wr_fh $hex, \n, $bytes, \n\n;

All looks great for now: you're calculating md5 and size, and writing it
into file with md5 extension...

 return($hex);

... but now you're abruptly jumping out of the while block, making the
whole point of cycle, well, completely pointless. Not great.

 close $wr_fh;
 close $fh;

}
 }




 # The following is mostly not original code - thanks to the author!

sub cleanup {
 my @filelist = readdir($totalin);
  foreach my $oldname (@filelist) {
 next if -d $oldname;
 my $newname = $oldname;
  $newname =~ s/\ //;

So you don't have spaces in your filenames. Great for you. )

 rename $oldname, $newname;
 }
 }


# End #


And here we finish.

Computers are not smart. They're dumb. But they're fast. And obedient. )
That's why they're really helpful in letting you do what you're trying to
do... but only if you KNOW what you're trying to do.

Imagine that you're - and not your computer - will be doing this task.
Sit in one place - and write down your program as you (and not your
computer) will be running it. Step by step. Bit by bit.

Then convert your notes into some Perl form - and you'll instantly see the
difference between now and then. )

-- iD


Re: passing arguments to perl function with - in the string

2011-11-29 Thread Igor Dovgiy
Hi Satya,

Might I suggest to look up a bit into the function's source code?
Because it's, well, pretty normal to call subs like that:
...
some_func_call(-chan_range = $beg-$end)
...

Of course, $beg and $end variables should be defined already (and contain
numeric values, as I see).
If not, warnings about attempting to interpolate undefined values will be
shown.

It's definitely not ok to use these without double quotation marks:
$beg-$end is just $beg minus $end.

-- iD

2011/11/29 Nemana, Satya snem...@sonusnet.com

 Hi



 Sorry for the silly question, but thought someone might help here.(tried
 googling but this may too silly a beginners question for anyone to have
 answered previously)

 I need to pass argument to a function like this  -chan_range =
 $chs-$che

 Normally when this used which works  -chan_range = 1-24

 However, when I try to put variable values instead of a scalar string, I
 get compilation errors (the errors are in different part of the code
 which is completely clueless)

 What is the correct way to pass the values with variable names and - in
 the string?

 I tried using \ and without the  also, but nothing helped.



 Thanks in anticipation,



 Regards,

 Satya






Re: sprintf function

2011-11-29 Thread Igor Dovgiy
googlesh perl is_numeric = http://www.perlmonks.org/?node_id=609478
qq{
Scalar::Util http://search.cpan.org/perldoc?Scalar%3A%3AUtil provides
access to the underlying Perl API looks_like_number routine which Perl
itself uses internally.
}

2011/11/29 Chris Stinemetz chrisstinem...@gmail.com

  How can I check that the value assigned to $cell and $sector is numeric
 before I try to call the sprintf function?

 I am just trying to clear this warning.

 Argument  isn't numeric in sprintf at ./rt_evdo_pcmd.pl line 139, $FIN
 line 119503.

 line 139 is from my program is below:

 my $c_s = sprintf(%d_%d,$cell,$sector);

 Thank you in advance.

 Chris



Re: Question regarding file stat setgid determination.

2011-10-31 Thread Igor Dovgiy
Hi Daniel,

There's no such thing as boolean literals [true/false] in Perl. ) Remember
these weird '1's at the end of .pm files? ) Or constructs like while(1)? )

And frankly speaking, I don't think there's a big need for these literals.
Every value (scalar or list, doesn't matter) can be well and happily
evaluated in boolean context, with little (if any) surprises in this
evaluation.

So, if you really need to return 1 from this function, just put !! before
booleaned value, like this. )
  my $isItSet =  !! ( $mode  Fcntl::S_ISGID )

... but then again, notice the word 'really'. ) And be aware that 'print
!!0' line will print you an empty string, not zero.

-- iD

2011/10/29 Daniel Patrick Sullivan dansulli...@gmail.com

 HI, All,

 I am banging my head against the wall on an issue that I think would
 be pretty simple; I'm trying to determine whether or not the current
 running script has the SetGUID file mode set on it and it is proving
 much more challenging than I had originally anticipated.  I am using
 OSX version 10.6 and perl version v5.10.0.

 Basically my function looks like this:

 use Fcntl;
 sub isCurrentFileSetGID() {
my $currentFile = $0;
my $mode = (stat($currentFile))[2];
print Mode:  . $mode . \n;
my $MyMask = Fcntl::S_ISGID;
print MyMask:  . Fcntl::S_ISGID . \n;
my $isItSet =  $mode  Fcntl::S_ISGID;
print iSItSet =  . $isItSet . \n;
return $isItSet;
 }

 For some reason, the S_ISGID constant is being interpreted as 1024,
 however I am uncertain why.  It appears as 0002000 in
 /usr/include/sys/fcntl.h:

 #define S_ISGID 0002000 /* [XSI] set group id on execution
 */

 When I execute the script, I am getting 1024 as the output for both
 the mask and the operation between the mask and the file mode.  Am I
 missing something here?  I would expect this to return 1.  Can
 somebody help me shed some light on this?  The output of my execution
 against a perl script with the setgid bit set is found below.

 wireless-s1-so-150-57-199:Perl dsullivan2$ ls -l
 total 8
 -rwx--x--x  1 dsullivan2  staff  731 Oct 29 05:55 pw7.pl
 wireless-s1-so-150-57-199:Perl dsullivan2$ chmod 2711 pw7.pl
 wireless-s1-so-150-57-199:Perl dsullivan2$ ls -l
 total 8
 -rwx--s--x  1 dsullivan2  staff  731 Oct 29 05:55 pw7.pl
 wireless-s1-so-150-57-199:Perl dsullivan2$ ./pw7.pl
 Mode: 34249
 MyMask: 1024
 iSItSet = 1024
 wireless-s1-so-150-57-199:Perl dsullivan2$

 Thank-you,

 Dan Sullivan
 312-607-3702

 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: regex help

2011-10-18 Thread Igor Dovgiy
Maybe this'll be helpful. )

my $time_rx = qr/(?timestamp
   (?hour \d{2} )
   (?: :\d{2} ){2}
 )
/x;

my $cell_record_rx = qr/CELL
  \s+
  (?cell_number \d+)
  \s+
  (?cell_info [^,]+)
 /x;

my $records_ref;
my $record_ts;
while () {
  if ($record_ts) {
# looking for record data of this particular timestamp
if (/$cell_record_rx/) {
  ++$records_ref-{$record_ts}{ $+{cell_number} }{ $+{cell_info} };
  undef $record_ts;
}
  }
  else {
#scanning for next valid record
if (/$time_rx/
 $+{hour} = 17  $+{hour} = 21) {
  $record_ts = $+{timestamp};
}
  }
}

-- iD

2011/10/18 Chris Stinemetz chrisstinem...@gmail.com

 On Mon, Oct 17, 2011 at 10:57 PM, Leo Susanto leosusa...@gmail.com
 wrote:
  From looking at the regex
 
   if ($line =~
 /17|18|19|20|21+:(\d+):(\d+)+\n+\n+CELL\s+(\d+)\s+(.+?),.+?HEH/){
 
  against the data
 
  10/17/11 18:25:20 #578030
 
   25 REPT:CELL 221 CDM 2, CRC, HEH
  SUPPRESSED MSGS: 0
  ERROR TYPE: ONEBTS MODULAR CELL ERROR
  SET: MLG BANDWIDTH CHANGE
  MLG 1 BANDWIDTH = 1536
 
  I would assume $1 and $2 wouldn't match to anything plus $5 doesn't
 exist.
 
  Could you please let us know which part of the data you want to extract?
 
  Fill in the blanks
  $1=
  $2=
  $3=
  $4=
  $5=
 

 Thanks everyone. I hope this clarifies what I am trying to match. For
 example with this input:

 10/17/11 18:25:20 #578030

  25 REPT:CELL 221 CDM 2, CRC, HEH
 SUPPRESSED MSGS: 0
 ERROR TYPE: ONEBTS MODULAR CELL ERROR
 SET: MLG BANDWIDTH CHANGE
 MLG 1 BANDWIDTH = 1536


 $1= Match the time stamp Hour:Min:Sec only if the hour is = 17 and hour =
 21
 $2= capture CELL number
 $3= capture the information after the CELL number (and before the first
 comma)

 Thank you,

 Chris

 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: Run perl scripts in Windows

2011-10-18 Thread Igor Dovgiy
Hello Remy,

I guess you may either convert this script with something like perl2exe (or
similar solutions),
or use the portable version of Strawberry Perl -
http://strawberryperl.com/download/5.12.3.0/strawberry-perl-5.12.3.0-portable.zip
- to run it.

-- iD

2011/10/18 Remy Guo rollingst...@gmail.com

 hi all,
 I have a Perl script in Windows but my system administrator doesn't allow
 me
 to install ActivePerl nor i guess anything that will change rigistry on the
 machine.
 is there any other way to run the script?

 Thanks..

 Remy



Re: How to put an AND in a regex?

2011-10-13 Thread Igor Dovgiy
Hmm, probably you should. To use two of them in AND combination, just... use
two of them. )

/^(?![[:upper:]][[:upper:]])(?!\d)/

And it gets even better: you may mix any number of look-aheads in a single
regex this way. )

-- iD

2011/10/13 Hamann, T.D. (Thomas) ham...@nhn.leidenuniv.nl


 Hi,

 I am trying to write a regex that should only match when certain patterns
 are not present, e.g. when a line does not start with either a digit or
 ALL-CAPS text. I figured I could use negative look-aheads for this.

 I can write it as:

 if (/^(?![[:upper:]][[:upper:]])/) {
if (/^(?!\d)/) {
s/^/test/;
}
else {
}
 }
 else {
 }

 However, I was wondering whether there was a way of writing this as a
 single if loop, because there are much more than two situations that should
 not be matched.

 I tried to write it as:

 if (/^(?![[:upper:]][[:upper:]])|^(?!\d)/) {
 s/^/test/;
 }
 else {
 }

 but this means if one option is not matched the other one is matched, which
 is not what I want. So I need something that does the equivalent of Don't
 match this AND don't match this. Is this possible in a if loop, or should I
 use something else?

 Thanks,

 Regards,
 Thomas Hamann

 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: don't know where to start??? comparing files

2011-10-13 Thread Igor Dovgiy
May be this'll help? )


#!/usr/bin/perl
use strict;
use warnings;
die 'Usage: ' . __FILE__ .  file1[ file2...]\n unless @ARGV;

my $ref_file =  'ref.txt';
my $new_file =  'new.txt';

open my $ref_fh, '', $ref_file
or die Failed to open reference file - $!\n;
my %limits_for;
while ($ref_fh) {
next unless /\d/; # skipping infoless lines
my ($chromosome, $start, $end) = split;
$limits_for{ $chromosome } = {
start   = $start,
end = $end,
};
}
close $ref_fh;

my %positions_for;
while () {
my ($chromosome, $pos) = split;
push @{ $positions_for{ $chromosome } }, $pos;
}

my %in_limits_for;
foreach my $chromosome (keys %positions_for) {
next unless exists $limits_for{ $chromosome };
my @in_limits = grep {
$limits_for{ $chromosome }-{start} = $_

$_ = $limits_for{ $chromosome }-{end}
} @{ $positions_for{ $chromosome } };
$in_limits_for{ $chromosome } = \@in_limits;
}

open my $new_fh, '', $new_file
or die Failed to write out results - $!\n;
foreach my $chromosome (keys %in_limits_for) {
foreach my $pos ( @{ $in_limits_for{ $chromosome } } ) {
printf $new_fh
   %-7s %15s\n, $chromosome, $pos;
}
print $new_fh '=' x 80 . \n;
}
close $new_fh;

-- iD

2011/10/12 Nathalie Conte n...@sanger.ac.uk

 HI All,
 I have 2 sets of files I want to compare,and I don't know where to start to
 get what I want :(
 I have a reference file ( see ref for example) with a chromosome name, a
 start and a end position
 Chr7115249090115859515
 Chr82525549629565459
 Chr13198276698298299815
 ChrX109100951109130998


 and I have a file (file_test) file I want to parse against this reference
 ref.txt
 Chr1115249098  Chr11362705  Chr825255996  Chr81362714  Chr1
1362735  ChrX109100997
 So if the position on the file_test is found in ref_file it is kept in a
 new file, if not discarded.

 I am looking for advises /modules I could use to compare those 2 files .
 many thanks in advance for any tips
 Nat


 --
 The Wellcome Trust Sanger Institute is operated by Genome Research Limited,
 a charity registered in England with number 1021457 and a company registered
 in England with number 2742969, whose registered office is 215 Euston Road,
 London, NW1 2BE.
 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: encoding and PDF::API2

2011-10-07 Thread Igor Dovgiy
Hi Marcos,

my %pdf_info = $pdf-info();
foreach (keys $pdf_info) {
$pdf_info{$_} =~ s/[^\x00-\xFF]//g;
}

Perhaps that'll do? )

-- iD

2011/10/7 marcos rebelo ole...@gmail.com

 Hi all

 I'm trying to get the info from a PDF with a code like:

 ###

 ...
 use Data::Dumper;
 use PDF::API2;
 ...
 my $pdf = PDF::API2-open('/home/.../PDF.pdf');
 print Dumper +{ $pdf-info() };

 ###

 This code gets me something like:

 ###

 $VAR1 = {
  'Subject' = 'my subject',
  'CreationDate' = 'D:20111006161347+02\'00\'',
  'Producer' = 'LibreOffice 3.3',
  'Creator' = 'Writer',
  'Author' = 'Marcos Rebelo',
  'Title' = 'my title',
  'Keywords' = 'my keywords'
};

 ###

 Unfortunatly someone has the code:  use encoding 'utf8'; 

 and now I get:

 ###

 $VAR1 = {
  'Subject' = \x{fffd}\x{fffd}my subject,
  'CreationDate' = 'D:20111006161347+02\'00\'',
  'Producer' = \x{fffd}\x{fffd}LibreOffice 3.3,
  'Creator' = \x{fffd}\x{fffd}Writer,
  'Author' = \x{fffd}\x{fffd}Marcos Rebelo,
  'Title' = \x{fffd}\x{fffd}my title,
  'Keywords' = \x{fffd}\x{fffd}my keywords
};

 ###

 I can't remove the  use encoding 'utf8'; , but I need to clean the hash.

 How can I clean the hash?


 Best Regards
 Marcos Rebelo

 --
 Marcos Rebelo
 http://www.oleber.com/
 Webmaster of http://perl5notebook.oleber.com

 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/





Re: Capitalizing Acronyms

2011-10-07 Thread Igor Dovgiy
You know, it shouldn't be mile long. )

$string =~ s! \b (?=[a-z]{3,4}) ([aeiouy]{3,4}|[^aeiouy]{3,4}) \b !\U$1!igx;

-- iD

2011/10/7 Marc sono...@fannullone.us

 On Oct 6, 2011, at 4:44 PM, Jim Gibson wrote:

  You should go back to your original character class of
 [bcdfghjklmnpqrstvwxz]

 Making this change fixed the Rex'S problem, but it didn't
 capitalize LKJ because the rest of the code had capitalized the acronym as
 Lkj.  So I changed that line to:
 $string =~
 s~\b([aeiouyAEIOUY]{3,4}|[bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ]{3,4})\b~uc$1~eg;

 and now it works, even though it's a mile long. ;)  Thanks for helping me
 to think about it differently.

 Marc
 --
 To unsubscribe, e-mail: beginners-unsubscr...@perl.org
 For additional commands, e-mail: beginners-h...@perl.org
 http://learn.perl.org/