• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst] awk Skripting

binbash

Newbie
Hallo an alle,

habe hier eine Datei die folgenden Inhalt hat

'/Nachrichten/Brandneu/Curling/q_s' 0.017
'/Nachrichten/Brandneu/Curling/q_sport' 0.484
'/useraccount/PersoenlicheStartseite.jsp' 0.027
'/tropssearch/simpleSearch.action' 5.640
'/useraccount/logout.action' 4.619
'/useraccount/Login.jsp' 0.529
'/poke/ConfirmSuperpoke.jsp' 0.552
'/tropssearch/ShowProfileSearchResultsOnly.jsp' 0.343
'/photos/AlbumAnzeigen.jsp' 3.771
'/useraccount/login.action' 0.019
'/useraccount/PersoenlicheStartseite.jsp' 2.021
'/useraccount/Login.jsp' 0.049
'/photos/TeamFotoAnzeigen.jsp' 0.308
'/Nachrichten/Deutsche-Ju-Jutsu-Meisterschaften-2008/event' 0.653
'/photos/TeamFotos.jsp' 0.359
'/index.jsp' 0.578
'/useraccount/login.action' 0.213
'/profile/Profil.jsp' 0.386
'/pub/d3989bfcaf0cc2654bd75f8c34ef9062' 0.081
'/photos/TeamAlbum.jsp' 0.177
'/useraccount/login.action' 0.118
'/useraccount/PersoenlicheStartseite.jsp' 0.635
'/useraccount/PersoenlicheStartseite.jsp' 1.551
'/friends/request.action' 0.095
'/profile/Profil.jsp' 0.324
'/team/Teamtopic.jsp' 0.269
'/team/OfferMembership.jsp' 0.107
'/photos/TeamFotoAnzeigen.jsp' 0.958
'/useraccount/PersoenlicheStartseite.jsp' 1.421
'/photocomments/createEntry.action' 0.124
'/Nachrichten/Fechten-Schache-Achte-bei-Florett-Weltcup-in-St-Petersburg/4035/a' 29.005
'/photos/MeineFotos.jsp' 0.167
'/photos/TeamFotoAnzeigen.jsp' 0.513
'/videos/Video.jsp' 0.032
'/pub/Sauerland_Mustangs' 0.259
'/Nachrichten/Golf/s' 0.016
'/photos/AlbumAnzeigen.jsp' 0.142
'/team/inviteMember.action' 0.574
'/Nachrichten/Golf/sport_page2' 1.394
'/notifier/log/ShowNotificationLogRequests.jsp' 0.147
'/profile/Profil.jsp' 0.448
'/useraccount/PersoenlicheStartseite.jsp' 1.156
'/useraccount/PersoenlicheStartseite.jsp' 1.152
'/photos/FotoAnzeigen.jsp' 0.123
'/photos/FotoAnzeigen.jsp' 0.154
'/Nachrichten/Havanna/ort' 0.304
'/team/requestMembership.action' 0.094
'/notifier/log/ShowNotificationLogRequests.jsp' 0.098
'/Nachrichten/Gordon-Geib/duser' 0.011
'/Nachrichten' 0.639
'/Nachrichten/Gordon-Geib/sportler' 0.398
'/notifier/log/ShowNotificationLogRequests.jsp' 0.311
'/photos/FotoAnzeigen.jsp' 0.148
'/useraccount/PersoenlicheStartseite.jsp' 1.044
'/useraccount/logout.action' 0.027
'/team/deleteInvitation.action' 0.102
'/sport/Sporttopic.jsp' 0.271
'/index.jsp' 0.658
'/tropssearch/simpleSearch.action' 7.102
'/Nachrichten/Massa-gewinnt-in-Istanbul/a' 3.707
'/notifier/log/ShowNotificationLogRequests.jsp' 7.361
'/photos/FotoAnzeigen.jsp' 5.346
'/useraccount/login.action' 3.027
'/tropssearch/simpleSearch.action' 4.905
'/useraccount/logout.action' 4.413
'/Nachrichten/florenz/verein' 0.423
'/index.jsp' 0.935
'/tropssearch/simpleSearch.action' 6.834
'/Nachrichten/Massa-gewinnt-in-Istanbul/Motorsport/8767/a' 9.440
'/tropssearch/ShowProfileSearchResultsOnly.jsp' 0.493
'/team/deleteInvitation.action' 3.659
'/photos/FotoAnzeigen.jsp' 4.977
'/photos/TeamAlbum.jsp' 4.060
'/team/deleteInvitation.action' 0.098
'/useraccount/login.action' 4.178
'/Nachrichten/Schock-bei-Pietsch-Diagnose-Brustkrebs/Schwimmen/5670248531252193223/a' 9.413
'/useraccount/PersoenlicheStartseite.jsp' 9.814
'/notifier/log/ShowNotificationLogRequests.jsp' 0.197
'/useraccount/PersoenlicheStartseite.jsp' 0.637
'/useraccount/PersoenlicheStartseite.jsp' 9.843
'/useraccount/PersoenlicheStartseite.jsp' 0.752
'/team/deleteInvitation.action' 0.087


Nun soll ich die 10 URLs bestimmen die in der Summe die größte Zugriffszeit haben (Neben der URL steht die Zugriffszeit)
Die meisten URLs kommen häufig vor und nur die sollen gezählt werden sprich diejenigen die nur einmal vorkommen entfallen

Die Datei hat 52305 Zeilen wobei wie gesagt viele Einträge öfters vorkommen

Danke
 
OP
binbash

binbash

Newbie
die frage würde lauten :

wie bekomme ich das mittels bash-skripting hin ?

bzw das problem ist das ich es nicht hin bekomme


ein beispiel
alle einträge in der datei /videos/Videos,jsp wären

'/videos/Video-nur-fuer-netzathleten.jsp' 0.499
'/videos/Video-nur-fuer-netzathleten.jsp' 4.017
'/videos/Videos.jsp' 0.290
'/videos/Videos.jsp' 0.302
'/videos/Videos.jsp' 0.303
'/videos/Videos.jsp' 0.306
'/videos/Videos.jsp' 0.320
'/videos/Videos.jsp' 0.325
'/videos/Videos.jsp' 0.330
'/videos/Videos.jsp' 0.335
'/videos/Videos.jsp' 0.342
'video/Video.jsp' 0.735

so ich hätte gerne für jeden block wie zb 'videos/Videos.jsp' eine eigene Datei mit passenden Inhalt (Nur Einträge mit '/videos/Videos.jsp') aus der ich dann die durchschnittliche Zugriffszeit ermittele

dann eine weitere Datei mit block-inhalt aus '/videos/Video-nur-fuer-netzathleten.jsp' usw usw ein gibt aber so viele Verzeichnisse das ich sie nie nicht händisch kopieren kann


Danke
 

Escho

Advanced Hacker
Nun soll ich die 10 URLs bestimmen die in der Summe die größte Zugriffszeit haben (Neben der URL steht die Zugriffszeit)
Die meisten URLs kommen häufig vor und nur die sollen gezählt werden sprich diejenigen die nur einmal vorkommen entfallen
Setz halt, wenigstens ab und zu, ein paar Kommas. Ich hab den Satz viermal lesen müssen, bis ich kapiert habe, was du überhaupt willst!

Edgar
 

abgdf

Guru
Laß' das mal laufen:
Code:
#!/usr/bin/env python
#-*- coding: iso-8859-1 -*-

import os
import sys
import sre

s = sys.argv
if len(s) < 2:
    print "\nGimme a file-name!\n"
    sys.exit(1)

fh = file(s[1], "r")
a = fh.readlines()
fh.close()

e = {}

for i in a:
    # Needed, if filename contains " ":
    b = sre.match("'.*'", i)
    c = b.group()

    d = float(i.split(c + " ")[1].rstrip("\n"))

    if e.has_key(c):
        e[c] += d
    else:
        e[c] = d

f = e.values()
f.sort(reverse = True)

g = e.items()

for i in range(10):
    for u in g:
        if f[i] == u[1]:
            print u[0] + " " + str(u[1])
            g.remove(u)
            break
Setz halt, wenigstens ab und zu, ein paar Kommas.
Dem kann ich mich nur anschließen!

Gruß
 
A

Anonymous

Gast
klassicher Fall für awk
Code:
awk '{zeit[$1]+=$2} END{for (name in zeit) print zeit[name], name }' DATEI | sort -nr
DATEI ist deine Logdatei und die ersten 10 Zeilen der Ausgabe sind deine 10 Treffer

robi
 
OP
binbash

binbash

Newbie
Danke für die Hilfe, (KOMMA) :)

ich habs nicht so mit den Kommas im Internet nicht übel nehmen.

Das Python-Skript und das awk-Kommando lass ich morgen durchlaufen und berichte näheres.
Nur sieht mir das ganze nicht schlüssig aus.

Ich versuche es nochmal kurz zu erklären.
Hier ist ne Datei die hat ca 54 000 Zeilen, in jeder Zeile findet sich eine URL und eine Zugriffszeit,
das ganze entspricht diesem Muster

'/example/beispiel' 0.765
'/example/beispiel' 0.354
'/fotos/fotos.jsp' 1.4
.... usw usw usw

Nun soll für jede URL die passende Datei erzeugt werden, wieder ein kleines Beispiel

'/videos/videos.jsp' 0.444 // Es sind ca 300 Einträge mit '/video/videos.jsp' vorhanden, diese Einträge zu '/videos/videos.jsp' sollen alle
in der gleichnamigen Datei, hier als Beispiel videosvideosjsp.txt landen

Und das ganze nochmals für /user/users.jsp, wobei nicht alle mit jsp enden zur Info


Ich danke euch
 
A

Anonymous

Gast
na mit landen und dabei noch 1000 Dateien anlegen das hatte ich so nicht verstanden, desshalb hab ichs ja auch gleich mal alles zusammengerechnet, na vielleicht kannst du trotzdem was damit anfangen.
Code:
/tmp # awk '{zeit[$1]+=$2} END{for (name in zeit) print zeit[name], name }' test5 | sort -nr
30.053 '/useraccount/PersoenlicheStartseite.jsp'
29.005 '/Nachrichten/Fechten-Schache-Achte-bei-Florett-Weltcup-in-St-Petersburg/4035/a'
24.481 '/tropssearch/simpleSearch.action'
10.748 '/photos/FotoAnzeigen.jsp'
9.44 '/Nachrichten/Massa-gewinnt-in-Istanbul/Motorsport/8767/a'
9.413 '/Nachrichten/Schock-bei-Pietsch-Diagnose-Brustkrebs/Schwimmen/5670248531252193223/a'
9.059 '/useraccount/logout.action'
8.114 '/notifier/log/ShowNotificationLogRequests.jsp'
7.555 '/useraccount/login.action'
4.237 '/photos/TeamAlbum.jsp'
3.946 '/team/deleteInvitation.action'
3.913 '/photos/AlbumAnzeigen.jsp'
3.707 '/Nachrichten/Massa-gewinnt-in-Istanbul/a'
2.171 '/index.jsp'
1.779 '/photos/TeamFotoAnzeigen.jsp'
........
Dein letzter Beitrag war jetzt übrigens klar und deutlich und auch noch verständlich. Es geht doch ;)

robi
 
OP
binbash

binbash

Newbie
Danke dir robi für deine Mühe, moren gegen 12 Uhr werde ich das Ergebnis posten.

a guats nächtle :)
 
OP
binbash

binbash

Newbie
Traceback (most recent call last):
File "user.py", line 24, in <module>
d = float(i.split(c + " ")[1].rstrip("\n"))
IndexError: list index out of range




Das sagt die Ausgabe nach dem ausführen des Python Skripts
 

abgdf

Guru
Hier ist ne Datei die hat ca 54 000 Zeilen,
Ok, sagen wir, die heißt "datei.dat". Dann mußt Du das Pythonskript, meinetwegen "user.py", mit
Code:
user.py datei.dat
starten. Achte auch beim Kopieren/Einfügen des Skript-Textes darauf, daß die Einrückungen erhalten bleiben.

Wichtig ist auch, daß die "datei.dat" genau so aussieht, wie von Dir beschrieben: Also keine leeren Zeilen dazwischen, am Anfang oder am Ende.

Probier' das Skript z.B. erstmal mit dem Dateiinhalt, den Du oben zuerst gepostet hast. Also, bei mir geht das.

Ausgabe sind bisher die 10 häufigsten URLs. Erst wenn das so läuft, könnte ich das für das Erzeugen von Dateien ergänzen.

Gruß

P.S.: Wäre auch nett, wenn auch die anderen das mal mit nachvollziehen würden. Ich meine, wie gesagt, daß es geht.
 
OP
binbash

binbash

Newbie
So robi wenn ich das ganze über die Orginaldatei rüber laufen lasse bekomme ich ich folgendes

user@tc3:~$ awk '{zeit[$1]+=$2} END{for (name in zeit) print zeit[name], name }' alles2.txt | sort -nr | head
8769.1 '/useraccount/PersoenlicheStartseite.jsp'
6445.48 '/profile/Profil.jsp'
2008 '/Nachrichten/Olympia
1693.34 '/index.jsp'
1676.63 '/messages/AntwortSchreiben.jsp'
1603.69 '/useraccount/login.action'
1545.21 '/profile/Profile.jsp'
1257.97 '/Nachrichten/Ski-alpin-Miller-kritisiert-Abfahrts-Absage/4793/a'
1217.03 '/tropssearch/simpleSearch.action'
1104.36 '/Nachrichten/Hambuechen-erreicht-vier-Finals/Turnen/1894866842701606711/a'

Mir scheints allerdings so als werden die Zeiten der Seiten nur addiert statt am Ende den Durchschnitt zu ermitteln ? Kann man das irgendwie realisieren?
Den Seiten wie '/useraccount/PersönlicheDaten.jsp' werden von jedem Mitglied beim Login aufgerufen seiten wie '/tropssearch/simpleSearch.action' jedoch selten und teilweise liegen dort die großen Zugriffszahlen

@abgdf

Die Formatierung der Datei sieht wie folgt aus:

'/url/url'<Freizeichen>Zeit
also als Beispiel
'/users/usersaccount.jsp' 1.766
..........
...........

Die Einrückungen des Skriptes bleiben beim kopieren erhalten, denoch meckert er wegen dem Index
Zwischen der URL und der Zeit ist jeweils ein Freizeichen, falls das hier nicht ersichtlich ist.


Traceback (most recent call last):
File "./user.py", line 22, in <module>
d = float(i.split(c + " ")[1].rstrip("\n"))
IndexError: list index out of range



Beste Gruesse
binbash
 
A

Anonymous

Gast
.........die in der Summe die größte Zugriffszeit ........
Hier steht nur was von Summe und nichts von "Durchschnitt" oder "arithmetischem Mittel" oder brauchst du nicht doch ein "winsorisiertes arithmetisches Mittel", und wie soll man "... kommen häufig vor und nur die sollen gezählt werden.... " mathematisch genau interpretieren? Oder ist nicht doch ein "arithmetischer gleitender Durchschnitt" angesagt? Da gibts noch 20 andere Mittelwerte .
Nun soll ich die 10 URLs bestimmen die in der Summe ......
Aha, Auftragsarbeit, dann den Auftraggeber mal nach der genauen mathematische Formel fragen, der sollte ja wissen, was er genau haben will. Schönen Gruß vom Linux-Club, und mit verschwommenen unscharfen Aufgabenstellungen kann niemand beim programmieren was anfangen.

Ansonsten : geht in awk alles recht komfortabel, nimmst eben eine zweite, dritte oder vierte Feldvariable noch dazu oder benutzt mehrdimensionale Felder , je nach dem auch noch ein paar mathematische Formeln und while-Schleifen und interpretierst die Formel die der Chef dir liefert, Sache von 5 Minuten (Nachdem du dich vorher natürlich erst mal ein paar Jahre intensiv mit awk beschäftigt hast) ;) ;) :???:

schau'mer heute abend mal, was wir für dich tun können.


robi
 
OP
binbash

binbash

Newbie
Hm ist natürlich etwas schwer zu formulieren.

Und noch ein kleines weiteres Beispiel :) vielleicht kann man sich damit eher ein Bild machen

'/video/video.jsp' existiert sagen wir mal 7 mal in der Datei mit jeweils anderen Zeiten


'/video/video.jsp' 0.756
'/video/video.jsp' 0.433
'/video/video.jsp' 0.544
'/video/video.jsp' 0.655
'/video/video.jsp' 0.654
'/video/video.jsp' 0.433
'/video/video.jsp' 0.332 Das die ganzen Zahlen die zu '/video/'video.jsp' gehören sollen addiert und dann hier durch Anzahl der vorhandenen Einträge von '/video/video.jsp' hier im Beispiel 7 dividiert werden, das ganze soll mit allen URLs geschehen, sprich

'/useraccount/user.jsp' 0.777
'/useraccount/user.jsp' 0.123 in diesem Fall die zwei Werte addieren und durch die Anzahl dividieren, sprich durch 2

Die höhsten 10 Werte kann man dann simpel emitteln mittels sort -n wenn die Auswertung des Skriptes in ne Datei umgelenkt wurde...

Mit awk, sed und python habe ich mich leider bisher noch nie befasst und anscheinend wäre das nun nötig gewesen, deshalb bitte ich hier um Hilfe.


Danke
 
A

Anonymous

Gast
Na dann versuch mal folgendes, ich kann es aber im Moment nicht selbst testen, mein XP versteht kein awk :D :D :D

Code:
awk '{zeit[$1]+=$2;zahl[$1]++ } END {for (name in zeit) if (zahl[name]>3) print zeit[name] / zahl[name],name}'  DATEI | sort -nr
(sollte alles in einer Zeile stehen, wenn dein Browser die Zeilen umbricht, dann eventuell anpassen)

Ignoriert wird alles was nicht mehr als 3 Mal vorkommt.

robi
 
OP
binbash

binbash

Newbie
ah hast es geändert, ich danke dir vielmals robi.


Eine Frage am Rande, wie sage ich grep er solle nur nach Mustern in der Datei suchen die ein '/ am anfang stehen haben ?

Oder besser gesagt ich versuche momentan die Durchschnittzeit nach Praefix zu ermitteln. Als Beispiel wenn jemand /videos/ eingibt soll die temporäre Datei nach der URL /videos/* durchsucht werden..
Die Ausgabe würde dann ungefähr so aussehen

'/videos/Video-nur-fuer-netzathleten.jsp' 0.183
'/videos/index.jsp' 1.476
'/videos/Video.jsp' 0.030
'/videos/Video-nur-fuer-netzathleten.jsp' 0.042
'/videos/Video.jsp' 0.035
'/videos/Video-nur-fuer-netzathleten.jsp' 0.022
'/videos/Video.jsp' 0.033
'/videos/Video-nur-fuer-netzathleten.jsp' 0.027
'/videos/Video.jsp' 0.033
'/videos/Video-nur-fuer-netzathleten.jsp' 0.051
'/videos/Video.jsp' 0.019
'/videos/Video-nur-fuer-netzathleten.jsp' 0.028
'/videos/Videos.jsp' 0.606
'/videos/Video.jsp' 0.027
'/videos/Video-nur-fuer-netzathleten.jsp' 0.024
'/videos/TeamVideo.jsp' 0.288
'/videos/Video.jsp' 0.046
'/videos/Video-nur-fuer-netzathleten.jsp' 0.031
'/videos/Video.jsp' 0.055
'/videos/Video-nur-fuer-netzathleten.jsp' 0.055
'/videos/TeamVideos.jsp' 0.153
'/videos/Video.jsp' 0.027
'/videos/Video-nur-fuer-netzathleten.jsp' 0.043
'/videos/Video.jsp' 0.026
'/videos/Video-nur-fuer-netzathleten.jsp' 0.043
'/videos/Videos.jsp' 0.532
'/videos/Video.jsp' 0.060
'/videos/Video-nur-fuer-netzathleten.jsp' 0.086
'/videos/Video.jsp' 0.045
'/videos/Video-nur-fuer-netzathleten.jsp' 0.071
'/videos/Video.jsp' 0.025
'/videos/Video-nur-fuer-netzathleten.jsp' 0.043
'/videos/Video.jsp' 0.036

Nun sollen nur die Zahlen addiert werden und durch die Anzahl der Zeilen dividiert werden.
Ausschlaggebend ist hier nur der Praefix '/videos/

#! /bin/bash

DATUM=$(date +%Y-%m-%d)

echo "Geben Sie den Praefix ein: ()"
read praefix

cat /tmp/statistic.$DATUM.txt | grep $praefix > /tmp/varx.$DATUM.txt
wk '{zeit[$1]+=$2;zahl[$1]++ } END {for (name in zeit) if (zahl[name]>3) print zeit[name] / zahl[name],name}' // die Zeile müsste nun verändert werden um die Zeiten zu addieren und dann durch die Anzahl zu dividieren




Gruesse
binbash
 

abgdf

Guru
Traceback (most recent call last):
File "./user.py", line 22, in <module>
d = float(i.split(c + " ")[1].rstrip("\n"))
IndexError: list index out of range
Merkwürdig ist schon, daß er über Zeile 22 meckern soll: Die Zeile mit "d = ..." ist bei mir in 24.

@robi: Leider gibt mein Python-Skript etwas andere Ergebnisse aus als Deine awk-Zeile :???: .

Gruß
 
A

Anonymous

Gast
abgdf schrieb:
@robi: Leider gibt mein Python-Skript etwas andere Ergebnisse aus als Deine awk-Zeile :???: .
Wer der Meinung ist das stimmt nicht, soll doch selbst nachrechen, ich behaupte einfach awk hat Recht ;)


Dein Python bekomme ich übrigens auch nicht ans laufen. :???: selber Fehler :???:


@binbash und nicht so viele unnötigen Befehl hintereinander,
Code:
cat | grep | awk
Alles rausgeschmissene Rechenzeit wenn man das über einen großen Datenbestand schickt, merkt man es deutlich
kann awk alles ganz alleine ;) ;) ;) ;)

Code:
#! /bin/bash
DATUM=$(date +%Y-%m-%d)

echo "Geben Sie den Praefix ein: ()"
read praefix
korr_praefix=`echo "$praefix" | sed 's#/#\\\\/#g'`  # eventuell Sonderzeichen '/' werden hier durch '\' maskiert.
                                                    # je Bedarf müssten eventuell weitere Sonderzeichen maskiert werden 
awk '/'"$korr_praefix"'/ {zeit+=$2;zahl++ } END { if (zahl>0) print zeit / zahl}' /tmp/statistic.$DATUM.txt


robi
 
Oben