Zitat von
herates
...
Dann habe ich mittels
Code:
cat druckdaten | awk '{print $2,$3,$6*$7,$9}' > druckdaten2
die datei was bereinigt, der druckername, das datum und - wurde entfernt. gleichzeitig wurde die anzahl der kopien mit der seitenzahl multipliziert.
Das heisst meien Datei sieht folgendermassen aus.
lokaler_nutzer jobID Anzahl_Seiten IP
zu beachten: da ich die dateien mit cat zusammenfasse habe ich blöcke deren JobIDs in sich ansteigen, dies gilt aber nicht für die gesamte datei.
was mir jetzt noch fehlt, ist die aussortierung des datensatzes mit der maximalen seitenzahl innerhalb derselben jobid-blöcke. da wurde mir bereits hier geholfen
hier aber da werde ich nicht schlau draus.
dann muss ich die seitenzahlen der lokalen user und der ip user zusammenfassen und ausgeben...
Die Seitenzahlen der lokalen / ip User gesamt oder für jeden Einzelnen? Und so schwer war der awk doch nun auch nicht
Also, ich versuche mal zusammenzufassen:
1. Du hast in der Datei druckdaten eine wilde Mischung aus Usern und Job-IDs
2. lokale Benutzer werden durch die User-ID (für remote-User immer "guest"), IP-User durch die IP-Adresse (für lokale Benutzer immer "localhost") identifiziert
3. Du willst nach wie vor für jeden Job eine Ausgabe der maximalen Seitennummer = Seitenanzahl
4. ??? Du willst zusätzlich pro User eine Summe des Druckaufkommens (Seiten * Kopien)
5. ??? Du willst zusätzlich eine Summe für alle lokalen und alle IP-User
OK, dann erweitern wir das Ganze mal.
Zuerst würde ich die Reihenfolge der Felder für die weitere Bearbeitung ändern. Wenn man Gruppenwechsel (also User-ID oder IP) identifizieren will, dann sollte die Eingangsdatei auch nach diesen Kriterien sortiert werden:
Code:
awk '{print $2,$9,$3,$6*$7;}' druckdaten | sort | awk -f prt_max_page.awk
Als Ausgabe hast Du eine zuerst nach User, dann IP und dann Job sortierte Liste. Die wird jetzt dem auswertenden Script übergeben.
Dazu habe ich das awk-Script entspr. erweitert (und gleich einen kleinen Bug mit der unnötigen chg-Variablen entfernt ;-):
Code:
BEGIN { # Initialisierung der benutzten Variablen
user = ""; # speichert den User-Namen fuer Vergleiche
ip = ""; # speichert die IP-Adresse
job = 0; # speichert die Job-ID
page = 0; # max. Seitenanzahl / Job
lcnt = 0; # Seiten lokaler User
rcnt = 0; # Seiten von IP-Usern
}
# hier beginnt die Verarbeitung der Zeilen
{ # 1. Zeile: Erstbefuellung der Variablen
if (user == "") {
user = $1;
ip = $2;
job = $3;
page = $4;
# Array Seiten / User fuer ersten initialisieren
if (user == "guest")
ucnt[ip] = 0;
else
ucnt[user] = 0;
}
# in aktueller Zeile aendert sich user oder ip: neuer User
if (user != "" && (user != $1 || ip != $2)) {
# letzten Job ausgeben
print user, ip, job, page;
# Seiten / User fuer letzten User addieren
if (user == "guest") {
ucnt[ip] += page;
rcnt += page;
}
else {
ucnt[user] += page;
lcnt += page;
}
# Variablen auf aktuellen Satz setzen
user = $1;
ip = $2;
job = $3;
page = $4;
# Seitenzahlen / User fuer naechsten User initialisieren
if (user == "guest")
ucnt[ip] = 0;
else
ucnt[user] = 0;
}
# gleicher User, gleiche IP, neuer Job
if (user == $1 && ip == $2 && job != $3) {
# Job ausgeben
print user, ip, job, page;
# Seitenanzahl aktueller User addieren
if (user == "guest") {
ucnt[ip] += page;
rcnt += page;
}
else {
ucnt[user] += page;
lcnt += page;
}
# Variablen auf aktuellen Satz setzen
job = $3;
page = $4;
}
# gleicher User, gleiche IP, gleicher Job: Seitenanzahl pruefen
if (user == $1 && ip == $2 && job == $3) {
if (page < $4) page = $4;
}
}
END { # diese Operationen werden nach der letzten Zeile durchgefuehrt
# letzte Daten drucken
print user, ip, job, page;
# letzte Seiten addieren
if (user == "guest") {
ucnt[ip] += page;
rcnt += page;
}
else {
ucnt[user] += page;
lcnt += page;
}
# Summen der einzelnen Benutzer ausgeben
for (user in ucnt) {
print "Summe ", user, ": ", ucnt[user], " Seiten";
}
print "Summe lokale Benutzer: ", lcnt, " Seiten";
print "Summe remote Benutzer: ", rcnt, " Seiten";
}
Das awk-Script liest die per STDIN (aus der Pipe) übergebenen Daten zeilenweise ein. Außerdem gibt es einen BEGIN- und einen END-Block:
Der BEGIN-Block wird vor dem Lesen der 1. Zeile ausgeführt, hier initialisiere ich die weiter unten benutzten Variablen (ist im awk eigentlich nicht nötig - sie werden bei der Erstbenutzung initialisiert, ich finde es aber übersichtlicher).
Dann kommt die Bearbeitung der 1. Zeile, wenn die Variable user noch nicht gefüllt ist (könnte man auch mit der internen Variablen NR erkennen): Hier werden alle Variablen auf die Werte der 1. Zeile gesetzt ($1 ... $4 sind die Felder user, ip, job, seiten aus der Eingabe) sowie ein assoziatives Array (Hash) für die Summe der Seiten des Benutzers initialisiert. Es wird zwischen lokalen und remote-Benutzern unterschieden, da bei ersteren der Username und bei letzteren die IP maßgeblich ist.
Der nächste Abschnitt: Wenn sich entweder der User oder die IP geändert hat, dann haben wir einen neuen User. Dann wird die Zeile mit den letzten Job-Daten des vorigen Benutzers (gespeichert in den Variablen user, ip, job, page) ausgegeben, die Anzahl der Seiten des letzten Jobs zu den Summen des Users addiert und die Variablen auf die Werte der aktuellen Zeile gesetzt (nächster User).
Wenn sich der Job, aber nicht user und ip geändert haben, dann wird der letzte Job des Users ausgegeben, die Seiten des letzten Jobs zur Summe im Array addiert und job sowie page auf die Werte der aktuellen Eingabezeile gesetzt.
Ändert sich weder user noch ip noch job, dann wird überprüft, ob die Seitenzahl der aktuellen Zeile höher ist als die bisher in page gespeicherte Maximalzahl für diesen Job und wenn ja übernommen.
Im END-Abschnitt (der nach der Auswertung der letzten Zeile ausgeführt wird) wird der letzte Job ausgegeben und die Seiten des letzten Jobs auf die des Users addiert. Dann wird in einer For-Schleife über das ucnt-Array die Summe der Seiten / Benutzer ausgegeben und zum Schluss noch die Summen der lokalen und remote-Benutzer.
Jan
P.S.: Wenn Du irgendwas im Code nicht verstehst, dann frage bitte einfach nach (ich setze voraus, dass Du Dich mit den genutzten Kommandos - speziell awk - auseinandergesetzt hast).
Lesezeichen