PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : bash programmierung - daten aus datei filtern



herates
19-08-2007, 19:17
hallo,
ich habe folgendes problem...

ich habe eine datei mit datensätzen. z.b.:

(user) (Job) (page) (IP) <----nur zur erläuterung
zi3101 46 1 localhost
zi3101 47 1 localhost
zi3101 47 2 localhost
zi3101 48 1 localhost
zi3101 48 2 localhost
zi3101 48 3 localhost
zi3101 48 4 localhost
zi3101 48 5 localhost
zi3101 48 6 localhost
zi3101 48 7 localhost
zi3101 48 8 localhost
zi3101 48 9 localhost
zi3101 48 10 localhost
zi3101 49 1 localhost
zi3101 50 1 localhost
zi3101 50 2 localhost
haus3 14 1 134.130.59.80
haus3 15 1 134.130.59.80
zi3101 16 1 localhost
zi3101 17 1 localhost
zi3101 17 2 localhost

jetzt will ich die letzte zeile jeder jobid behalten, und zwar die mit der maximal page. der rest ist müll.

bsp: jobid 48
es bleibt übrig
zi3101 48 10 localhost

wie ihr seht bilden die jobid pakete. die pakete selbst sind aber nicht sortiert. innerhalb eines jobid pakets sind die pages ansteigend sortiert.

ich hoffe es ist klar geworden, was ich versuche zu realisieren????

wie kann ich das mittel bash script realisieren???

für die, die es interessiert, dies ist eine bereits gefilterte page_log von cups.

wolfgang

jan61
19-08-2007, 21:42
Moin,

das geht z. B. mit awk (ich habe Deine Beispieldaten mal in eine Textdatei jobs.txt gepackt und noch ein wenig durcheinandergewürfelt):
jan@jack:~/tmp/cups_test> cat prt_max_page.awk
BEGIN { user = "";
job = 0;
page = 0;
ip = "";
chg = 0;
}
{ # 1. Zeile
if (user == "") {
user = $1;
job = $2;
page = $3;
ip = $4;
}
# neuer User
if (user != "" && user != $1) {
print user, job, page, ip;
user = $1;
job = $2;
page = $3;
ip = $4;
chg = 1;
}
# neuer Job
if (user == $1 && job != $2) {
print user, job, page, ip;
job = $2;
page = $3;
chg = 1;
}
# gleicher User, gleicher Job: Seitenanzahl pruefen
if (user == $1 && job == $2) {
if (page < $3) page = $3;
chg = 0;
}
}
END {
# nur, wenn in der letzten Zeile nichts Neues kam: letzte Daten drucken
if (chg == 0)
print user, job, page, ip;
}
jan@jack:~/tmp/cups_test> sort jobs.txt | awk -f prt_max_page.awk
haus3 14 1 134.130.59.80
haus3 15 1 134.130.59.80
zi3101 16 1 localhost
zi3101 17 2 localhost
zi3101 46 1 localhost
zi3101 47 2 localhost
zi3101 48 10 localhost
zi3101 49 1 localhost
zi3101 50 2 localhost
Die Datei prt_max_page.awk enthält awk-Kommando-Code (sieht fast so wie C aus), die dann per awk -f prt_max_page.awk aufgerufen wird. Der sort zum Anfang garantiert, dass die Daten je User und Job hintereinander kommen (ich hatte nicht ganz kapiert, wie die Sortierung in den Ausgangsdateien ist). sort in der hier benutzten Variante sortiert alphanumerisch, so dass Du die Job-Nummern unter Umständen nicht numerisch sortiert erhältst: 1, 10, 11, 2, ... (wenn Du das nicht willst, dann schau Dir mal man sort an). Die Sortierung der Seiten spielt keine Rolle, da sie numerisch innerhalb des awk-Scripts verglichen werden.

Jan

herates
20-08-2007, 10:39
hi, danke.

durch den awk code steige ich zwar nicht ganz durch, aber das wird schon. aber es klappt ja :)