Hallo Team,
2 Logdateien (Text) mit dem Format liegen mir vor. Logdatei A mit 43 Einträgen von Tag 1
user_a datum account klicks
user_d datum account klicks
user_b datum account klicks
user_c datum account klicks
...
Logdatei B mit 55 Einträgen von Tag 2
user_c datum account klicks
user_d datum account klicks
user_a datum account klicks
user_b datum account klicks
...
Die numerischen Werte "Klicks" möchte ich so auswerten, daß gerechnet wird :
Klicks von Tag 2 minus Klicks von Tag 1, Ergebnis in neuer Datei mit der größeren useranzahl,
also 55 user, dh. 12 user ohne ergebnis.
Ergebnisdatei mit 55 Einträgen
user_a diff_klicks
user_b diff_klicks
user_c diff_klicks
user_d
user_e
...
im Logdateinamen A und B ist das Tagesdatum enthalten. Da ich sicherstellen will daß keine neg. klicks ausgerechnet werden, muß der Tag 1 von Tag 2 abgezogen werden ( in Tag 2 wurden die klicks aufkummuliert ).
Probiert habe ich folgendes:
mit awk '{print $1 $4}' Tag1.log komme ich schon mal an die user und Klicks
Natülich stehen die user "durcheinander", d.h zum user_a aus Tag1.log muß der user_a aus Tag2.log gefunden werden.
Habt ihr eine Shellscript / Bash -lösung parat ?
Wäre super.
System: DEB Lenny 5.04
gruß root2root
Berechnungen mit der Bash
Re: Berechnungen mit der Bash
Code: Alles auswählen
#!/bin/sh
analyze() {
USERS=$(awk '{print $1}' "$FILE" | sort | uniq)
for i in $USERS ; do
egrep "^$i" "$FILE" | awk '{print $1,"x","x",SUM+=$4}' | tail -n1
done
}
FILE=LogA
analyze | awk '{print $1,"x","x",-$4}'> TempC
FILE=LogB
analyze >> TempC
FILE=TempC
analyze | awk '{print $1,$4}' > Out
ich hänge dann aber erstmal an einer Formulierung
Code: Alles auswählen
awk '$1=="$i" ...'
Und statt des 'tail' hat awk bestimmt auch eine Möglichkeit, nur die Gesamtsumme auszugeben.)
Die "x", damit ich die Funktion dreimal anwenden kann.
Schneller und resourcenschonender wird das Einlesen der Dateien in Arrays ('read'),
und das Anwenden von Aktionen auf die Array-Elemente sein.
Aber meine Version ist auch nur ein dummer shell-Hack.
Sowas zum Beispiel:
Code: Alles auswählen
(
exec 9<$0 <LogA
while read a b c d; do
echo $a \-$d
done
exec 9<$0 <LogB
while read a b c d; do
echo $a $d
done
) | sort
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
Re: Berechnungen mit der Bash
wenns nicht unbedingt die bash sein muss eignet sich perl für sowas ganz gut. der Perl Code ist zwar nicht kürzer, liest sich aber IMO etwas einfacher.
Code: Alles auswählen
#! /usr/bin/perl
use strict;
use warnings;
my $path = "/SOME_PATH/";
my %hash1; my %hash2;
my ($key, $date, $val);
open (FILE1, "<$path" . "datei1.log");
open (FILE2, "<$path" . "datei2.log");
open (FILE3, ">>$path" . "diff.log");
while (<FILE1>) {
chomp;
($key, $date, $val) = split / /;
$hash1{$key} = $val;
}
while (<FILE2>) {
chomp;
($key, $date, $val) = split / /;
$hash2{$key} = $val;
}
foreach $key (keys %hash2) {
if ($hash1{$key} and $hash2{$key}) {
print FILE3 ($key, " " , $hash2{$key} - $hash1{$key}, "\n");
}
else {
print FILE3 ($key, " " , $hash2{$key}, "\n");
}
}
close FILE1; close FILE2; close FILE3;