Re: hashes and loops

2005-06-15 Thread Dave Gray
On 6/14/05, Karyn Williams [EMAIL PROTECTED] wrote:
 Below is code that I found on the web that I slightly modified. I am trying
 to create a script to remove from a file (tlist) the items in another file
 (tnames). This works but I have multiple files (tlist) I need to check
 against. I'm not sure how/where to put the loop and would appreciate any
 help. I am also wondering why the hash ? Does it work better in  the script
 than an array and what are the keys in this case as the files (both) are
 just lists of e-mail addresses.

If you're not set on using perl for all of this, grep (if available)
can do a lot of the work for you:

# create fake suppression lists
 perl -e 'print [EMAIL PROTECTED] for d .. p;'  exclude1
 perl -e 'print [EMAIL PROTECTED] for C .. F;'  exclude2
# create fake email list
perl -e 'print [EMAIL PROTECTED] for a .. z, A .. Z;'  source
# print emails in the list not in either suppression list
grep -f exclude1 -f exclude2 -v source

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: hashes and loops

2005-06-15 Thread John W. Krahn

Karyn Williams wrote:


  [snip]


So, first question is why is this happenning ? Then how do I fix it ?


What is happening that you didn't want to happen?  What is NOT happening that 
you did want to happen?


http://www.catb.org/~esr/faqs/smart-questions.html


Also,
there are just a handful of files BUT they are ever changing, so I would
like to not list the statically in the code. Would a 


@lists = qw (`ls /usr/local/dir`);

work ?


No, because qw() creates the list ( '`ls', '/usr/local/dir`' ) but this would 
work:


chomp( my @lists = qx(ls /usr/local/dir) );


But this would work a lot better:

my @lists = glob '/usr/local/dir/*';




John
--
use Perl;
program
fulfillment

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: hashes and loops

2005-06-15 Thread Karyn Williams
At 07:42 AM 6/15/05 -0700, you wrote:
Karyn Williams wrote:

 Also,
 there are just a handful of files BUT they are ever changing, so I would
 like to not list the statically in the code.  
 
but this would work:

chomp( my @lists = qx(ls /usr/local/dir) );

But this would work a lot better:

my @lists = glob '/usr/local/dir/*';

I added the glob and it worked great. However, I need to restrict @lists to
include only files that do not have extensions. I have been playing around
with this trying variations on glob and just plain regexes. i.e.

chomp( my @lists = '/usr/local/majordomo/lists/*[^(\.config|\.bak)]');
chomp( my @lists = /usr/local/majordomo/lists/*[^(\.config|\.bak)]);
chomp( my @lists = qx(ls -A1
/usr/local/majordomo/lists/*[^(\.config|\.bak)]));
chomp( my @lists = qx(ls -A1 /usr/local/majordomo/lists/(.*(?=[^.])));
chomp( my @lists = /usr/local/majordomo/lists/\w+(?=[^.]));
my @lists = glob '/usr/local/majordomo/lists/*[^(\.config|\.bak)]';

but I am not getting anywhere. Perl 5.6.1 on Solaris. Am I even close ?

-- 

Karyn Williams
Network Services Manager
California Institute of the Arts
[EMAIL PROTECTED]
http://www.calarts.edu/network

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: hashes and loops

2005-06-15 Thread John W. Krahn

Karyn Williams wrote:

At 07:42 AM 6/15/05 -0700, you wrote:


Karyn Williams wrote:



Also,
there are just a handful of files BUT they are ever changing, so I would
like to not list the statically in the code.  


but this would work:

chomp( my @lists = qx(ls /usr/local/dir) );

But this would work a lot better:

my @lists = glob '/usr/local/dir/*';


I added the glob and it worked great. However, I need to restrict @lists to
include only files that do not have extensions. I have been playing around
with this trying variations on glob and just plain regexes. i.e.

chomp( my @lists = '/usr/local/majordomo/lists/*[^(\.config|\.bak)]');
chomp( my @lists = /usr/local/majordomo/lists/*[^(\.config|\.bak)]);
chomp( my @lists = qx(ls -A1
/usr/local/majordomo/lists/*[^(\.config|\.bak)]));
chomp( my @lists = qx(ls -A1 /usr/local/majordomo/lists/(.*(?=[^.])));
chomp( my @lists = /usr/local/majordomo/lists/\w+(?=[^.]));
my @lists = glob '/usr/local/majordomo/lists/*[^(\.config|\.bak)]';

but I am not getting anywhere. Perl 5.6.1 on Solaris. Am I even close ?


As you have found out you can't use regular expressions in a file glob however 
this should do what you want:


my @lists = grep m!/[^/.]+$!, glob '/usr/local/dir/*';


John
--
use Perl;
program
fulfillment

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




RE: hashes and loops

2005-06-14 Thread Wagner, David --- Senior Programmer Analyst --- WGO
Karyn Williams wrote:
 Below is code that I found on the web that I slightly modified. I am
 trying to create a script to remove from a file (tlist) the items in
 another file (tnames). This works but I have multiple files (tlist) I
 need to check against. I'm not sure how/where to put the loop and
 would appreciate any help. I am also wondering why the hash ? Does it
 work better in  the script than an array and what are the keys in
 this case as the files (both) are just lists of e-mail addresses.
 
Are all the files w/in the same directory or scattered? Are there 2 or 
500?

If only a few, then could create an array which has the filenames:

my @MyTlist = qw (file1 file2 file3 file4);
Now you could loop off this like:
 foreach my $file2 ( @MyTlist ) {
   open (FILE2, $file2 ) or die $!;
   while (file2 ) {
   chomp;
   push @missing,$_ unless (exists($compare{$_}));;
   }
   close(file2 );
  }

Now you can write out all that are not true.

If there are a large number and say in one directory, then use opendir, readdir 
to get the files you want and use a simliar setup as above.

Wags ;)
 #!/bin/perl
 
 my %compare = ();
 open (file1, /usr/local/tools/tnames) or die $!;
 while (file1) {
 chomp;
 $compare{$_}++;
 }
 close(file1);
 
 open (file2, /usr/local/tools/tlist) or die $!;
 while (file2) {
 chomp;
 push @missing,$_ unless (exists($compare{$_}));;
 }
 close(file2);
 #print $_\n for @missing;
 
 open (file3, /usr/local/tools/tlist1) or die $!;
 print file3 join(\n,@missing);
 print file3 (\n);
 close (file3);
 
 
 TIA
 
 --
 
 Karyn Williams
 Network Services Manager
 California Institute of the Arts
 [EMAIL PROTECTED]
 http://www.calarts.edu/network



***
This message contains information that is confidential
and proprietary to FedEx Freight or its affiliates.
It is intended only for the recipient named and for
the express purpose(s) described therein.
Any other use is prohibited.
***


--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: hashes and loops

2005-06-14 Thread Jeff 'japhy' Pinyan

On Jun 14, Karyn Williams said:


Below is code that I found on the web that I slightly modified. I am trying
to create a script to remove from a file (tlist) the items in another file
(tnames). This works but I have multiple files (tlist) I need to check
against. I'm not sure how/where to put the loop and would appreciate any
help. I am also wondering why the hash ? Does it work better in  the script
than an array and what are the keys in this case as the files (both) are
just lists of e-mail addresses.


The logic of the hash is as follows.  A hash, unlike an array, uses 
arbitrary strings as its keys.  Therefore, your hash %compare has the 
email addresses found in the tnames file as its keys.  Their corresponding 
values are numbers (specifically, as per your code, the number of times 
that email address was found in the tnames file).


To determine if a particular email address was in the tnames file, then, 
all you need to do is see if it is a key of your %compare hash:


  if (exists $compare{'[EMAIL PROTECTED]'}) {
# it's in there
  }

This is MONUMENTALLY faster than using an array:

  chomp(my @email_address = file1);

  # now we need to search the array for an email address:
  my $seen = 0;
  for (@email_address) {
if ($_ eq '[EMAIL PROTECTED]') {
  $seen = 1;
  last;
}
  }

The hash takes care of the searching for us, and very efficiently.

As for doing this to multiple files, I'd use a couple of Perl's tricks to 
get it done quickly and painlessly:


  # hash of email addresses to exclude from other files
  my %exclude;
  open my($names), $tnames_file or die can't read $tnames_file: $!;
  while ($names) {
chomp;
$exclude{$_} = 1;
  }
  close $names;

  # now comes the magic...
  {
local $^I = .bak;  # we're going to keep backups of the files
 # so if we read tlist-1, Perl automatically
 # backs it up as tlist-1.bak

local @ARGV = @files_to_search;  # this is an array of the files
 # from which we want to remove the
 # email addresses found in %exclude

# this while loop does everything for us:
# the empty  operator reads from the files listed in @ARGV, and for
# each one, it executes the code inside the loop.  whatever we print
# inside the loop gets printed to the new version of the file we're
# working on (remember, the file got backed up as xxx.bak before we
# started reading it).  our code simply says:  unless the email
# address is found in the %exclude hash, print it.  so this is doing
# the job of reading EACH line of EACH file, and ONLY printing those
# lines which are not found in the %exclude hash.

while () {
  chomp;
  print $_\n unless $exclude{$_};
}
  }

Presto!

  perldoc perlrun (for $^I and @ARGV and  magic -- see the -i option)

--
Jeff japhy Pinyan %  How can we ever be the sold short or
RPI Acacia Brother #734 %  the cheated, we who for every service
http://japhy.perlmonk.org/  %  have long ago been overpaid?
http://www.perlmonks.org/   %-- Meister Eckhart

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




RE: hashes and loops

2005-06-14 Thread Karyn Williams
At 04:37 PM 6/14/05 -0700, you wrote:
Karyn Williams wrote:
 Below is code that I found on the web that I slightly modified. I am
 trying to create a script to remove from a file (tlist) the items in
 another file (tnames). This works but I have multiple files (tlist) I
 need to check against. I'm not sure how/where to put the loop and
 would appreciate any help. I am also wondering why the hash ? Does it
 work better in  the script than an array and what are the keys in
 this case as the files (both) are just lists of e-mail addresses.
 
   Are all the files w/in the same directory or scattered? Are there 2 or 
 500?

If only a few, then could create an array which has the filenames:

my @MyTlist = qw (file1 file2 file3 file4);
Now you could loop off this like:
 foreach my $file2 ( @MyTlist ) {
   open (FILE2, $file2 ) or die $!;
   while (file2 ) {
   chomp;
   push @missing,$_ unless (exists($compare{$_}));;
   }
   close(file2 );
  }

Now you can write out all that are not true.

If there are a large number and say in one directory, then use opendir,
readdir to get the files you want and use a simliar setup as above.

Wags ;)

While waiting for replies I maanged to come up with this: which is very
similar to what you have. However see the results below the code. Not so good.

# cat rm_test1.pl
#!/bin/perl

my %compare = ();
open (file1, /usr/local/tools/tnames) or die $!;
while (file1) {
chomp;
$compare{$_}++;
}
close(file1);

@lists = (sa-art, sa-dance);
foreach $list (@lists) {


open (file2, $list) or die $!;
while (file2) {
chomp;
push @missing,$_ unless (exists($compare{$_}));;
}
close(file2);
#print $_\n for @missing;

open (file3, $list) or die $!;
print file3 join(\n,@missing);
print file3 (\n);
close (file3);
}

# cat sa-art
karyn
ador
adam
sue
betty
jerry

# cat sa-dance
karyn
ador
adam
sue
betty
jerry

karyn
ador
adam
sue
betty
jerry

#

So, first question is why is this happenning ? Then how do I fix it ? Also,
there are just a handful of files BUT they are ever changing, so I would
like to not list the statically in the code. Would a 


@lists = qw (`ls /usr/local/dir`);

work ?

I have not yet tried Japhy's code. But I have some questions about it I'll
post tomorrow.




 #!/bin/perl
 
 my %compare = ();
 open (file1, /usr/local/tools/tnames) or die $!;
 while (file1) {
 chomp;
 $compare{$_}++;
 }
 close(file1);
 
 open (file2, /usr/local/tools/tlist) or die $!;
 while (file2) {
 chomp;
 push @missing,$_ unless (exists($compare{$_}));;
 }
 close(file2);
 #print $_\n for @missing;
 
 open (file3, /usr/local/tools/tlist1) or die $!;
 print file3 join(\n,@missing);
 print file3 (\n);
 close (file3);
 
 
 TIA
 
 --
 
 Karyn Williams
 Network Services Manager
 California Institute of the Arts
 [EMAIL PROTECTED]
 http://www.calarts.edu/network



***
This message contains information that is confidential
and proprietary to FedEx Freight or its affiliates.
It is intended only for the recipient named and for
the express purpose(s) described therein.
Any other use is prohibited.
***



-- 

Karyn Williams
Network Services Manager
California Institute of the Arts
[EMAIL PROTECTED]
http://www.calarts.edu/network

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




RE: Hashes and loops

2001-09-19 Thread Daniel Falkenberg

 List,
 
 I have the following while loop that goes and pings a whole heap of
servers around our company.  If one is broken or doesn't respond to the
ping my code e-mails me the results of which server isn't responding.
This all works well but I really need it to be able to keep pinging all
the servers and if one breaks I need the hostname of that to be stored
in hash.  Ie a new hash.  
 
 First hash (Ping all these servers)
 
 %first_hash (
 
 1server.com' = 'Server1',
 2server.com' = 'Server2',
 3server.com' = 'Server3',
 4server.com' = 'Server4'
 
 }
 
 The script pings all the above servers.  Then if one doesn't respond
and nothing is returned.  Then I create another hash...
 
 %second_hash; #server that didn't resond to ping request. 
 
 This is all easy but I need my script to continue pinging the other
servers every 4 minutes.  And also keep checking the servers in the
second hash for con ectivity and if they are conected I need the key
from the second hash placed back into the first hash because it is live
again.
 
 I just need a quick tutorial on how I would go about this ?
 
 Hope this makes sense :)
 
 Regards,
 
 Dan
 
 
 while (1) {
  $sleep   = 5; #Sleep time in seconds. Have this at around 5 minutes
or 300 seconds
  $server  = 'mail.server.com';  #Mail server.  Change to suit other
environments
  $p   = Net::Ping-new(icmp, 1, 2);  #Ping object.  Uses icmp
protocal
  foreach $host (sort keys (%host)) {
  unless ($p-ping($host)) {
print $host hello \n;
 $name = $host{$host}; #Name of the machine/host
 %mail   = ( To  = '[EMAIL PROTECTED]',
 From= '[EMAIL PROTECTED]',
 Subject = $subject,
 Message = $message,
 SMTP= $server,
 );
 sendmail(%mail) or die $Mail::Sendmail::error;
 delete $host{$host};
 }
 }
 sleep $sleep;
 }

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]