Counting the differences based on a specific rule


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Counting the differences based on a specific rule
# 1  
Old 09-07-2008
Counting the differences based on a specific rule

Hi,
I've been trying to create a perl file to run something very specific. But I'm not getting any success. I'm not very good with hashing.

I have a file with two columns (tab separated) (already sorted)

99890 +
100281 +
104919 -
109672 +
113428 -
114501 +
115357 +
115598 -
116100 +
118192 +
119470 +

What I am trying to do is determine the difference between two sets of numbers only when a + is followed by a -. And then based on the difference value, to count those that are less than 100, 100-200, 201-500, 501-750, 751-1000, or greater than 1001 and also to determine how many didn't follow the rule (+ followed by -).

Based on the file above, I would assume the output would be:
<100 - 0
100-200 - 0
201-500 - 1
501-750 - 0
751-1000 - 0
>1001 - 2

no match - 5

Please if anyone can help me...
Thanks.
# 2  
Old 09-07-2008
Why do you need a hash for that? Just keep a list of differences and at the end sort through the list and loop over it, spitting out a report and resetting the count at the limits you have specified. While reading and calculating differences, increment a separate counter when you see a plus line, and decrement it when you see a minus line; this will be the count of unmatched plus lines.
# 3  
Old 09-07-2008
I see, well that makes sense.

so I could run it so it would search for + followed by a - and then take the difference between the two numbers.

How do I store the information so it knows to subtract out the two numbers when the expression is true? I guess this is why I was having a hard time with this.

Thanks for your help Smilie.
# 4  
Old 09-08-2008
You keep the previous value in a variable. As per your example, we don't need to worry about two consecutive lines with minuses on them.

Code:
while (<>) {
  die "Invalid input" unless m/^(\d+) ([-+])$/);
  my ($number, $sign) = ($1, $2);  # as captured by the previous regex match
  if ($sign eq '+') {
    ++$plusses;
    $previous = $number;
    next;
  }
  # else, must be a minus
  --$plusses;
  push @differences, $previous - $number;
}

# 5  
Old 09-08-2008
Thank you era! It makes sense now. what i did was this

Code:
while (<>) {
	chomp;
  #die "Invalid input" unless m/^(\d+) ([-+])$/);
  my ($number, $sign) = split("\t");  # as captured by the previous regex match
  if ($sign eq '+') {
    ++$plusses;
    $previous = $number;
    next;
  }
  # else, must be a minus
  --$plusses;
	push @differences, $number - $previous;
	print $number - $previous, "\n";
}

I wasn't sure if 'push @differences' was needed? So i just printed the values (I reversed the subtraction because I was getting negative numbers). I guess I can then use some if expressions to count each category.
# 6  
Old 09-08-2008
dont know what I was thinking. the $plusses gives me the no match and I can use the difference in another expression to print it out. Great, exactly what i need Smilie.
# 7  
Old 09-08-2008
Hi, so here is my attempt at this. Thank you era for your insight. Much appreciated!!

Code:
#!/usr/bin/perl 

#use strict;
use warnings;


my ($plusses, $previous, @differences, $h, $diff_value);
$value_100 = '0'; $value_200 = '0'; $value_500 = '0'; $value_750 = '0'; $value_1000 = '0'; $value_1001 = '0';
while (<>) {
	chomp;
  #die "Invalid input" unless m/^(\d+) ([-+])$/);
  my ($number, $sign) = split("\t");  # as captured by the previous regex match
  if ($sign eq '+') {
    ++$plusses;
    $previous = $number;
    next;
  }
  # else, must be a minus
  --$plusses;
	push @differences, $number - $previous;
	$diff_value = $number - $previous;
	if ($diff_value <= 100){
		$value_100++;
		}elsif ($diff_value > 100 && $diff_value <=200){
			$value_200++;
				}elsif ($diff_value >200 && $diff_value <=500){
				$value_500++;
					}elsif ($diff_value >500 && $diff_value <=750){
					$value_750++;
						}elsif ($diff_value >750 && $diff_value <=1000){
						$value_1000++;
							}else {
							$value_1001++;
							}
			
	
}
my $total_value = $value_100 + $value_200 + $value_500 + $value_750 + $value_1000 + $value_1001;
print "\nDistribution:\n";
print "<100 \t\t-\t$value_100\n";
print "100 - 200\t-\t$value_200\n";
print "201 - 500\t-\t$value_500\n";
print "501 - 750\t-\t$value_750\n";
print "751 - 1000\t-\t$value_1000\n";
print ">1001\t\t-\t$value_1001\n";
print "\t\t\t======\n";
print "TOTAL:\t\t\t$total_value\n";
print "\nNo matches: ",$plusses, "\n\n";

what do you think?
Login or Register to Ask a Question

Previous Thread | Next Thread

6 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Linux/Shell script - How to compare 2 arrays based on patterns and get the differences

I have FILE 1 (This file has all master columns/headers) A|B|C|D|E|F|G|H|STATUS FILE 2 A|C|F|I|OFF_STATUS 3|4|5|4|Y 6|7|8|5|Y Below command give me all headers of FILE 2 into array2.txt file paste <(head -1 FILE2.txt | tr '|' '\n')>array2.txt So I would like to compare... (2 Replies)
Discussion started by: jmadhams
2 Replies

2. UNIX for Dummies Questions & Answers

Extracting combined differences based on a single column

Dear All, I have two sets of files. File 1 can be any number between 1 and 20 followed by a frequency of that number in a give documents... the lines in the file will be dependent to the analysed document. e.g. file1 1,5 4,1 then I have file two which is basicall same numbers but with... (2 Replies)
Discussion started by: A-V
2 Replies

3. IP Networking

Facing issue in ip6table rule for port based routing management

Hi, Please help me on issue described below, I have 4 machine setup, M1 -> M2 -> M3 | M4. And A laptop that can be reachable through both M3 and M4. M2 has 2 NIC conected to M3 and M4. Now I want to divide the flow coming from M1 for laptop. At M2, I have done following,... (1 Reply)
Discussion started by: rahulbhansali24
1 Replies

4. Shell Programming and Scripting

Counting non-specific occurrences within a file.

I'm pretty new to scripting and didn't see an example of this issue yet. I am trying to count and print the total number of times each value is found within a file. Here is a short example of my starting file. value 3 value 3 value 3 value 3 value 4 value 6 value 6 value 6 value 6... (3 Replies)
Discussion started by: funkynmr
3 Replies

5. Shell Programming and Scripting

Regex based Rule engine.

Hi, Greetings. We need to make a regexp based rule engine. The rules would be applied to any file specified and the data not matching should be logged. Would awk be the right scripting language. Regards, Dikesh Shah. (2 Replies)
Discussion started by: dikesm
2 Replies

6. Shell Programming and Scripting

Counting specific words from the log

Hi, I need a shell script which can provide details from error logs like this Aug 23 21:19:41 red mountd: authenticated mount request from bl0110.bang.m pc.local:651 for /disk1/jobs (/disk1) Aug 23 08:49:52 red dhcpd: DHCPDISCOVER from 00:25:90:2b:cd:7c via eth0: unknown client Aug 24... (2 Replies)
Discussion started by: ratheeshp
2 Replies
Login or Register to Ask a Question