LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-21-2005, 09:03 AM   #1
vous
Member
 
Registered: Mar 2003
Location: Macondo
Distribution: Mandrake 9.1, 10.1, SuSE 8.1 pro, 10.1, Red Hat 8.0/9.0
Posts: 380

Rep: Reputation: 30
How can I sort out the first and last of a list of uniques?!?!!


Hello All,

I am trying to analyze a whole bunch of entries in my log files, and I'm stuck at this point...

I would like to go through this list:

20050312,RED,54343717
20050313,RED,54343717
20050316,RED,54343717
20050317,RED,54343717
20050318,RED,54343717
20050311,BLUE,54355389
20050318,BLUE,54355389
20050318,GREEN,54355555
20050320,GREEN,54355555

And get the following out:

1- Based on the 2nd and 3rd fields (thus for the first entry it would be this for example: "RED,54343717" <---so this would be used as the unique identifier) I would like to know 3 things:

a. How many occurances are of each (regardless of the first date field obviously).
b. When was the first time it came up.
c. When was the last time it came up.

Any thoughts?
 
Old 03-21-2005, 09:11 AM   #2
farmerjoe
Member
 
Registered: Oct 2004
Location: Texas
Distribution: Ubuntu - Home, RHEL4 - Server
Posts: 96

Rep: Reputation: 15
I think there are a number of ways to do this, but i will post what just popped in my head.

User grep.

Quote:
a. How many occurances are of each (regardless of the first date field obviously).
grep -c "RED,54343717" $FILE


##This should give you the number of times it found that string.

Quote:
b. When was the first time it came up.
grep -n "RED,54343717 $FILE | head -1

##This should give you the first match it found, along with the line number.


Quote:
c. When was the last time it came up.

grep -n "RED,54343717 $FILE | tail -1


#This should give you the last match it found, along with the line number.
 
Old 03-21-2005, 09:21 AM   #3
vous
Member
 
Registered: Mar 2003
Location: Macondo
Distribution: Mandrake 9.1, 10.1, SuSE 8.1 pro, 10.1, Red Hat 8.0/9.0
Posts: 380

Original Poster
Rep: Reputation: 30
Indeed, that's how you could do it one by one.

What I need is to have this done inside a loop that would produce this output automatically based on that list.

Expected output would be something like:

RED,54343717 .......5 times....First time: 20050312....Last time:20050318
BLUE,54355389......2 Times....First time:20050311.....Last time: 20050318
GREEN,54355555.....2 Times....Firsttime:20050318....Last time: 20050320


Any thoughts how this could be done in a loop????

Last edited by vous; 03-21-2005 at 09:27 AM.
 
Old 03-21-2005, 11:04 AM   #4
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
Try this php code :
PHP Code:
#!/usr/bin/php
<?php
if(count($argv) < 2) {
    die(
"Usage: ".$argv[0]." file...");
}

$DATAS = Array();

$file fopen($argv[1], "r");

if(!
$file) {
    die(
"could not open ".$argv[1]." in reading mode\n");
}

while((
$data fgetcsv($file128",")) !== FALSE) {
    
$DATAS[$data[1]][$data[2]][] = $data[0];
}

fclose($file);

foreach(
$DATAS as $color => $data) {
    
$i 0;
    foreach(
$data as $number => $dates) {
        
$i count($dates);
        echo 
"$color,$number......$i";
        echo 
"Times.....First time:";
        echo 
$dates[0].".....Last time:".$dates[$i-1]."\n";
    }
}
?>
Call it for example: report.php, chmod +x it and run it as
./report.php /path/to/your/file

Last edited by keefaz; 03-21-2005 at 11:22 AM.
 
Old 03-21-2005, 11:20 AM   #5
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 61
Edit: Got it!

Last edited by homey; 03-21-2005 at 11:22 AM.
 
Old 03-21-2005, 11:24 AM   #6
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
I just edited my post, also make sure your file looke like :
20050312,RED,54343717
20050313,RED,54343717
20050316,RED,54343717
20050317,RED,54343717
20050318,RED,54343717
20050311,BLUE,54355389
20050318,BLUE,54355389
20050318,GREEN,54355555
20050320,GREEN,54355555

Note that fgetcsv($file, 128, ",") while explode the current line with a "," delimiter
and in my loop, 3 fields are required ($data[0],[1],[3])
 
Old 03-21-2005, 12:12 PM   #7
vous
Member
 
Registered: Mar 2003
Location: Macondo
Distribution: Mandrake 9.1, 10.1, SuSE 8.1 pro, 10.1, Red Hat 8.0/9.0
Posts: 380

Original Poster
Rep: Reputation: 30
thanks keefaz, it'll take me a bit till I transport this to bash....

I'll let you know what comes out of it...
 
Old 03-21-2005, 04:54 PM   #8
TheLinuxDuck
Member
 
Registered: Sep 2002
Location: Tulsa, OK
Distribution: Slack, baby!
Posts: 349

Rep: Reputation: 33
Ok, so I'm a big fat nerd. People always tell me that I should use a different tool, than bash, for some of the scripting things that I want to do.. and I scoff.. openly.. and mockingly.. (=

So, using farmerjoe's grep examples, I created a bash script to do this.. I noticed you said something about converting it to bash or something, so here's my take on it:
Code:
#!/bin/bash

datafile='./data';

#  hold which items have been found and displayed
#
used=""

#  assume that no line will ever contain a space
#
for line in `cat $datafile`; do
  pieces=( `echo "$line" | tr ',' ' '` )  # 0-date 1-colorname 2-value

  #  see if we've examined this one before
  #
  item="${pieces[1]},${pieces[2]}"
  in_used=`echo "$used" | grep "$item"`

  #  if it's not yet been examined
  #
  if [ -z "$in_used" ]; then
    #  first, add it to the used list
    #
    used="$used $item"

    count_l=`grep -c "$item" $datafile`
    first_l=( `grep "$item" $datafile | head -1 | tr ',' ' '` )
    last_l=( `grep "$item" $datafile | tail -1 | tr ',' ' '` )
    printf "$item\t$count_l times\tfirst: $first_l\tlast: $last_l\n"
  fi
done
Assuming that the file "./data" contains the data you listed above, and assuming that the file is in cronological order by date, the output should be:
Code:
~/bash> ./parse.sh
RED,54343717    5 times first: 20050312 last: 20050318
BLUE,54355389   2 times first: 20050311 last: 20050318
GREEN,54355555  2 times first: 20050318 last: 20050320
 
Old 03-22-2005, 09:05 AM   #9
vous
Member
 
Registered: Mar 2003
Location: Macondo
Distribution: Mandrake 9.1, 10.1, SuSE 8.1 pro, 10.1, Red Hat 8.0/9.0
Posts: 380

Original Poster
Rep: Reputation: 30
Hi "TheLinuxDuck",

thanks a bunch!

This did it!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
C++, using custom function to sort an std::list R00ts Programming 3 01-03-2005 09:41 AM
get list of latest list of packages bobwall Linux - Distributions 1 11-30-2004 03:48 PM
wireless channel list different from router's list heluani Linux - Laptop and Netbook 1 08-29-2004 10:04 PM
sort pantera Programming 5 05-26-2004 07:36 PM
Inserting element to a list of list in C suwandy_chandra Programming 2 03-09-2004 03:08 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:18 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration