The UNIX and Linux Forums  

Go Back   The UNIX and Linux Forums > Top Forums > Shell Programming and Scripting
Google UNIX.COM


Shell Programming and Scripting Post questions about KSH, CSH, SH, BASH, PERL, PHP, SED, AWK and OTHER shell scripts here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
How ls | wc -l works? krishmaths UNIX for Dummies Questions & Answers 3 04-11-2008 01:16 PM
Help it works but its to SLOW Garlandxj Shell Programming and Scripting 10 04-03-2008 12:17 AM
Works with FTP but not NFS pbonilla UNIX for Dummies Questions & Answers 1 01-08-2008 02:31 PM
How the for loop works? neelaksh UNIX for Dummies Questions & Answers 6 02-04-2007 10:42 AM
how it works hosts jgutierrez29 UNIX for Dummies Questions & Answers 1 06-08-2005 01:37 PM

Reply
 
Submit Tools LinkBack Thread Tools Search this Thread Display Modes
  #1  
Old 04-22-2008
Registered User
 

Join Date: Mar 2008
Posts: 18
Still trying to get a grep -c that works

I am trying to get a count of each line

sub runit2 {
my ($file1a, $file2a) = @_;
my $file1_vala = $file1a->get;
my $file2_vala = $file2a->get;
open (FILE1a, "$file1_vala") or die;
open (FILE2a, "$file2_vala") or die;
chomp(my @strings = <FILE2a>);
while (1) {
foreach $pattern (<FILE1a>) {
chomp($pattern);
last if $pattern =~ /^\s*$/;
my @matches = eval {
grep $pattern eq $_, @strings;
};
if ($@) {
print "Error: $@";
} else {
my $count = @matches;
print "$count $pattern \n",
#$text->insert('end', "$count $pattern $_\n");
}
}
return;
}





1 ip routing
1 ip classless
1 no ip bootp server
1 no ip http server
1 no ip http secure-server
1 ip bgp-community new-format
1 no access-list 23
1 no access-list 51
1 logging buffered 4096 debugging
1 banner motd ^
6 *************************************************
6**************************************************
2 ^
1 banner exec ^
6**************************************************
2 * LEGAL NOTICE *
6 ***************************************************
6 ***************************************************
2 * LEGAL NOTICE *
6 ****************************************************
2 ^
1 ip dhcp excluded-address 10.8.26.1 10.8.26.100
1 ip dhcp excluded-address 10.8.26.200 10.8.26.254
1 no auto-summary
1 snmp-server view BLOCK iso included
1 snmp-server view BLOCK ipAddrEntry.*.*.*.*.* included
1 snmp-server view BLOCK ipAddrEntry.*.10.*.*.* excluded
1 snmp-server view BLOCK ipNetToMediaEntry.*.*.*.*.*.* included
1 snmp-server view BLOCK ipNetToMediaEntry.*.*.10.*.*.* excluded
1 snmp-server view BLOCK atEntry.*.*.*.*.*.*.* included
1 snmp-server view BLOCK atEntry.*.*.*.10.*.*.* excluded
2 snmp-server ifindex persist
2 snmp-server enable traps snmp authentication linkdown linkup coldstart warmstart
1 snmp-server enable traps frame-relay
1 snmp-server enable traps frame-relay subif
1 snmp-server enable traps config
1 ip tacacs source-interface loopback0
1 snmp-server trap-source loopback0
1 ip flow-export source fa0/0
1 ip flow-export version 5 origin-as
1 ip flow-export destination 10.15.1.2 9996
1 ip flow-cache timeout active 1
1 ip flow-cache timeout inactive 15
2 snmp-server ifindex persist
1 logging trap notifications
1 logging source-interface fa0/0
2 snmp-server enable traps snmp authentication linkdown linkup coldstart warmstart
1 privilege exec level 1 traceroute
1 privilege exec level 1 ping
1 privilege exec level 1 show configuration
1 line con 0
2 exec-timeout 5 0
3 login
1 line aux 0
2 exec-timeout 5 0
3 login
1 line vty 0 4
1 exec-timeout 30 0
1 no privilege level 15
1 no access-class 23 in
3 login
1 end


The easiest thing to look at is the 3 login lines. login appears in file 2 3 times. I only want a single output of "3 login" and not that statement every time the script encounters login.
Reply With Quote
Forum Sponsor
  #2  
Old 04-22-2008
era era is offline
Herder of Useless Cats
 

Join Date: Mar 2008
Location: /there/is/only/bin/sh
Posts: 3,650
You still want to drop the eval. Trust me on this, it's not doing anything useful.

Save the matches to a hash and print it only at the end. One of the earlier threads where you asked about this had a solution which did that.

Code:
foreach $pattern (<FILE1a>) {
  chomp($pattern);
  last if $pattern =~ /^\s*$/;
  my $matches = grep $pattern eq $_, @strings;
  ++$count{$pattern} if $matches;
}

for my $key (keys %count) {
  print "$count{$key} $key\n";
}
You need to declare %count up at the top if you use strict (which you should). Also the initialization before the for loop can stay as before. The endless while loop I don't understand; what's that for? Also you should probably close your files when you're done with them, especially if this is going to be a subroutine in a bigger program.
Reply With Quote
  #3  
Old 04-22-2008
Registered User
 

Join Date: Mar 2008
Posts: 18
Here is the exact sub that I now have in the script

#***********************
sub runit2 {
my ($file1a, $file2a) = @_;
my $file1_vala = $file1a->get;
my $file2_vala = $file2a->get;
open (FILE1a, "$file1_vala") or die;
open (FILE2a, "$file2_vala") or die;
$text->insert('end', "Device config contains: \n");
chomp(my @strings = <FILE2a>);
while (1) {
foreach $pattern (<FILE1a>) {
chomp($pattern);
last if $pattern =~ /^\s*$/;
my @matches = eval {
#grep /$pattern/, @strings;
grep $pattern eq $_, @strings
};
if ($@) {
print "Error: $@";
} else {
my $count = @matches;
$text->insert('end', "$count $pattern \n");
}
}
return;
}
close FILE1a;
close FILE2a;
}

If I take out the infinite while loop, the output is

"Device config contains:
1 no service tcp-small-servers"

Thats it, no further iteration.

If I leave it in, a snip of the output which is really not desirable ...

.
.
.
.
.
2 snmp-server enable traps snmp authentication linkdown linkup coldstart warmstart
1 snmp-server enable traps frame-relay
1 snmp-server enable traps frame-relay subif
1 snmp-server enable traps config
1 ip tacacs source-interface loopback0
1 snmp-server trap-source loopback0
1 ip flow-export source fa0/0
1 ip flow-export version 5 origin-as
1 ip flow-export destination 10.15.1.2 9996
1 ip flow-cache timeout active 1
1 ip flow-cache timeout inactive 15
2 snmp-server ifindex persist
1 logging trap notifications
1 logging source-interface fa0/0
2 snmp-server enable traps snmp authentication linkdown linkup coldstart warmstart
1 privilege exec level 1 traceroute
1 privilege exec level 1 ping
1 privilege exec level 1 show configuration
1 line con 0
2 exec-timeout 5 0
3 login
1 line aux 0
2 exec-timeout 5 0
3 login
1 line vty 0 4
1 exec-timeout 30 0
1 no privilege level 15
1 no access-class 23 in
3 login
1 end



If I modify the code above to

#***********************
sub runit2 {
my ($file1a, $file2a) = @_;
my $file1_vala = $file1a->get;
my $file2_vala = $file2a->get;
open (FILE1a, "$file1_vala") or die;
open (FILE2a, "$file2_vala") or die;
$text->insert('end', "Device config contains: \n");
#*******************************
foreach $pattern (<FILE1a>) {
chomp($pattern);
last if $pattern =~ /^\s*$/;
my $matches = grep $pattern eq $_, @strings;
++$count{$pattern} if $matches;
}

for my $key (keys %count) {
print "$count{$key} $key\n";
}
#*******************************
close FILE1a;
close FILE2a;
}

I would expect the hash to be printed in the "dos" window.

If the following is included, I get very many errors.

use strict
%count = ();

If omitted, nothing is printed to the dos window, but it does run.
Reply With Quote
  #4  
Old 04-22-2008
Registered User
 

Join Date: Mar 2008
Posts: 18
Sorry ...

This line is also included in sub ..

chomp(my @strings = <FILE2a>);

Hosed my cut and paste.
Reply With Quote
  #5  
Old 04-22-2008
era era is offline
Herder of Useless Cats
 

Join Date: Mar 2008
Location: /there/is/only/bin/sh
Posts: 3,650
When you use strict, all of your code needs to be strict. It's a hassle at first but it's useful when you start getting useful warnings when the code doesn't do what you expect. If your code is not strict, tackle that later. But adopt it in the next script you write. It's good for you.

The last will quit the foreach loop on the first blank or empty line. If you have empty lines in the patterns file, you probably mean "next", not "last".

If you have the same pattern multiple times in the pattern file, you will get multiple prints of the count of matches. I was under the impression that you were getting 1 login 2 login 3 login but now I see that you have 3 login 3 login 3 login, so it's simply reporting the same pattern multiple times. Welp, you can use a hash to prevent that, too.

Code:
sub runit2 {
  my ($file1a, $file2a) = @_;
  my $file1_vala = $file1a->get;
  my $file2_vala = $file2a->get;
  open (FILE1a, "$file1_vala") or die;
  open (FILE2a, "$file2_vala") or die;
  chomp(my @strings = <FILE2a>);
  close FILE2a;
  $text->insert('end', "Device config contains: \n");
  #*******************************
  foreach $pattern (<FILE1a>) {
    next if $pattern =~ /^\s*$/;
    next if $handled{$pattern};
    $handled{$pattern} = 1;
    chomp($pattern);
    my $matches = grep $pattern eq $_, @strings;
    next unless $matches;
    $text->insert('end', "$matches $pattern \n");
  }
  close FILE1a;
}

Last edited by era; 04-22-2008 at 01:55 PM. Reason: Optimize so $handled goes before grep
Reply With Quote
Google The UNIX and Linux Forums
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes




All times are GMT -7. The time now is 12:14 PM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited.
The UNIX and Linux Forums Content Copyright ©1993-2008. All Rights Reserved.Ad Management by RedTyger Visit The Complex Event Processing Blog

Content Relevant URLs by vBSEO 3.2.0