Anzeige:
Ergebnis 1 bis 7 von 7

Thema: Awk Hilfe gesucht

  1. #1
    Moderator Avatar von geronet
    Registriert seit
    23.05.2001
    Ort
    Grainau
    Beiträge
    96

    Awk Hilfe gesucht

    Hallo Leute,

    hab hier so eine kleine Aufgabe, bei der ich nicht weiterkomme. Ich bräuchte wenigstens mal einen Ansatz...

    Gegeben ist eine Textdatei, die folgende Zeilen aufweist:
    Code:
    Datum,Zeit,Adr,ID-Nr.,HST,Nr.,Wert,Einheit,Beschreibung,Art,Modul,SP-Nr.,Tarif
    13.07.05,20:00,1,51650097,SPX,1, 0000000.9,10^3 kWh,energy,instant.,0,0,0
    13.07.05,20:00,1,51650097,SPX,2, 0000036.0,m^3,volume,instant.,0,0,0
    13.07.05,20:00,1,51650097,SPX,3, 0000000.0,m^3/h,volume flow,instant.,0,0,0
    13.07.05,20:00,1,51650097,SPX,4, 0000000.0,kW,power,instant.,0,0,0
    13.07.05,20:00,1,51650097,SPX,5, 035.2,°C,flow temperature,instant.,0,0,0
    13.07.05,20:00,1,51650097,SPX,6, 047.3,°C,return temperature,instant.,0,0,0
    13.07.05,20:00,1,51650097,SPX,7, 000000,mK,temperature difference,instant.,0,0,0
    13.07.05,20:00,1,51650097,SPX,8, 51650097,"",fabrication #,instant.,0,0,0
    13.07.05,20:00,1,51650097,SPX,9, 51650097,"",customer location,instant.,0,0,0
    13.07.05,20:00,1,51650097,SPX,9,$10,"",M-Bus state,"","","",""
    13.07.05,20:00,2,50750217,SPX,1, 0000035.5,10^3 kWh,energy,instant.,0,0,0
    13.07.05,20:00,2,50750217,SPX,2, 0001191.9,m^3,volume,instant.,0,0,0
    13.07.05,20:00,2,50750217,SPX,3, 0000000.0,m^3/h,volume flow,instant.,0,0,0
    13.07.05,20:00,2,50750217,SPX,4, 0000000.0,kW,power,instant.,0,0,0
    13.07.05,20:00,2,50750217,SPX,5, 053.2,°C,flow temperature,instant.,0,0,0
    13.07.05,20:00,2,50750217,SPX,6, 057.3,°C,return temperature,instant.,0,0,0
    13.07.05,20:00,2,50750217,SPX,7, 000000,mK,temperature difference,instant.,0,0,0
    13.07.05,20:00,2,50750217,SPX,8, 50750217,"",fabrication #,instant.,0,0,0
    13.07.05,20:00,2,50750217,SPX,9, 50750217,"",customer location,instant.,0,0,0
    13.07.05,20:00,2,50750217,SPX,9,$10,"",M-Bus state,"","","",""
    Jetzt möchte ich diese Daten in eine RRD-Datenbank eintragen. Mit awk wäre das doch einigermassen möglich, da es ja zeilenbasierend ist.
    Das Problem ist nur
    a) Zeit+Datum vorne in Sekunden seit 1970 umzuwandeln
    b) Die Zählernummer (Adr, drittes Feld) so zu verwenden dass jeder (Wärme-)Zähler eine eigene RRD-Datei bekommt (oder auch nur eigene Datenquellen, alle in einer Datei)
    c) den eigentlichen Wert herauszufischen und dann so z.B. als bash-Aufruf auszugeben:
    Code:
                        # Zeit           Wert1       Wert2      Wert3 ...
    rrdtool update 1125694905:0000000.9:0000036.0:0000000.0:...
    Wäre echt nett von euch

  2. #2
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Ich glaube nicht dass Awk oder die Bash Datumsmanipulationsfunktionen haben die das können.

    Ich denke am besten versuchst dus irgendwie mit Perl (das hat da ein Modul Date::Manip) das das vermutlich kann.

    Der Rest sollte mit Perl auch nicht soo ein Problem sein - mal abgesehen davon dass ich nicht wirklich Perl kann


    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  3. #3
    Registrierter Benutzer Avatar von Romanday
    Registriert seit
    03.02.2004
    Beiträge
    829
    Du kannst aus einem AWK Script auch andere Programme starten.
    Für deine Umwandlung des Datums bietet sich z. B.

    http://www.php.net/manual/de/function.mktime.php

    an.
    Abriss, bzw. die Sprengung des World Trade Centers
    WDR Dokumentation
    Doku + DT Untertitel
    Weitere Infos - Terrorstorm

  4. #4
    Registrierter Benutzer
    Registriert seit
    05.09.2002
    Ort
    Neuhausen
    Beiträge
    320
    Eine schöne Aufgabe, ich nehme dafür Python, da ich schon viele ähnliche Aufgaben damit gelöst habe. Das folgende Beispiel geht davon aus, dass die Zähler immer in korrekter Reihenfolge gelistet werden, wenn nicht, ist das nur ein kleiner Änderung die Nr. zu berücksichtigen.

    Code:
    import sys, time, os
    
    FN = { 'date':0, 'time':1, 'addr':2, 'id':3, 'hst':4, 'no':5, 'value':6,
           'unit':7, 'desc':8, 'type':9, 'modul':10, 'sp-no':11, 'cost':12 }
    
    sources = {}
    
    sys.stdin.readline()  # remove header
    
    for line in sys.stdin.xreadlines():
        fields = line.split(',')
        if len(fields) != len(FN):
            continue
        s = " ".join((fields[FN['date']], fields[FN['time']]))
        timestamp = int(time.mktime(time.strptime(s, "%d.%m.%y %H:%M")))
        if not sources.has_key(timestamp):
            sources[timestamp] = {}
        key = fields[FN['addr']]
        if not sources[timestamp].has_key(key):
            sources[timestamp][key] = []
        sources[timestamp][key].append(fields)
    
    for timestamp in sources.iterkeys():
        for address in sources[timestamp].iterkeys():
            values = []
            for fields in sources[timestamp][address]:
                values.append(fields[FN['value']].strip())
            cmd = ("rrdtool update %s:" % timestamp) + ":".join(values)
            print "Address %s:" % address, cmd
            #os.system(cmd)
    Gruss, Andy
    Geändert von RapidMax (05-09-2005 um 21:17 Uhr)

  5. #5
    Moderator Avatar von geronet
    Registriert seit
    23.05.2001
    Ort
    Grainau
    Beiträge
    96
    Vielen Dank, Andy!

    Das ist genau das, was ich brauche

  6. #6
    Registrierter Benutzer
    Registriert seit
    05.09.2002
    Ort
    Neuhausen
    Beiträge
    320
    Zitat Zitat von geronet
    Das Script funktioniert wunderbar, nur bringt er mir die Zeiten durcheinander.
    Ich bin davon ausgegangen, dass die Reihenfolge keine Rolle spielt. Die Reihenfolge stimmt nicht mehr, weil die Datensätz in einem Dictionary gespeichert werden. Das ist zwar sehr schnell (Hash-Table lookup), aber eben ohne die Beibehaltung der ursprünglichen Reihenfolge.

    Ich hatte aber auch schon genau das Problem. Ich habe es so gelöst, dass ich zusätzlich zum Hinzufügen in das Dictionary den Datensatz in eine Liste fülle. Braucht zwar Speicher, kostet aber fast nichts (nur eine Einfüge-Operation im Vergleich zum linearen Durchsuchen einer Liste). Damit kannst du die ursprüngliche Reihenfolge beibehalten.

    In deinem Fall bist du nicht auf die ursprüngliche Reihenfolge angewiesen, sondern kannst am Schluss einfach eine Liste aus den Keys generieren und sortiern:

    Code:
    import sys, time, os
    
    FN = { 'date':0, 'time':1, 'addr':2, 'id':3, 'hst':4, 'no':5, 'value':6,
           'unit':7, 'desc':8, 'type':9, 'modul':10, 'sp-no':11, 'cost':12 }
    
    sources = {}
    
    sys.stdin.readline()  # remove header
    
    for line in sys.stdin.xreadlines():
        fields = line.split(',')
        if len(fields) != len(FN):
            continue
        s = " ".join((fields[FN['date']], fields[FN['time']]))
        timestamp = int(time.mktime(time.strptime(s, "%d.%m.%y %H:%M")))
        if not sources.has_key(timestamp):
            sources[timestamp] = {}
        key = fields[FN['addr']]
        if not sources[timestamp].has_key(key):
            sources[timestamp][key] = []
        sources[timestamp][key].append(fields)
    
    ordered = sources.keys()
    ordered.sort()
    
    for timestamp in ordered:
        for address in sources[timestamp].iterkeys():
            values = []
            for fields in sources[timestamp][address]:
                values.append(fields[FN['value']].strip())
            cmd = ("rrdtool update %s:" % timestamp) + ":".join(values)
            print "Address %s:" % address, cmd
            #os.system(cmd)
    Das gleich könntest du auch für Adressen machen, falls dort die Reihenfolge ebenfalls wichtig ist.

    Gruss, Andy

  7. #7
    Moderator Avatar von geronet
    Registriert seit
    23.05.2001
    Ort
    Grainau
    Beiträge
    96
    Ich schreib hier nur nochmal das fertige Script hin:

    Code:
    #!/usr/bin/python
    
    import sys, time, os
    
    FN = { 'date':0, 'time':1, 'addr':2, 'id':3, 'hst':4, 'no':5, 'value':6,
           'unit':7, 'desc':8, 'type':9, 'modul':10, 'sp-no':11, 'cost':12 }
    
    numbers =  (1,3,5,7,9,11,13,15,19,21,25,27)
    numbers2 = (1,2,3,4,5,6,7)
    sources = {}
    
    print 'converting %s...' % sys.argv[1]
    file = open(sys.argv[1], 'r')
    
    file.readline()  # remove header
    
    info = os.popen("rrdtool info /var/lib/kkh/1.rrd | grep last_update | awk '{print $3}'")
    last_update = int(info.readline())
    info.close()
    
    print "Last update: %s" % last_update
    
    for line in file.xreadlines():
        fields = line.split(',')
        if len(fields) != len(FN):
            continue
        s = " ".join((fields[FN['date']], fields[FN['time']]))
        timestamp = int(time.mktime(time.strptime(s, "%d.%m.%y %H:%M")))
        if int(timestamp) <= last_update:
            continue
        if not sources.has_key(timestamp):
            sources[timestamp] = {}
        key = fields[FN['addr']]
        if not sources[timestamp].has_key(key):
            sources[timestamp][key] = []
        sources[timestamp][key].append(fields)
    
    ordered = sources.keys()
    print 'sorting...'
    ordered.sort()
    
    print 'updating...'
    for timestamp in ordered:
        for address in sources[timestamp].iterkeys():
            values = []
            for fields in sources[timestamp][address]:
                value = fields[FN['value']]
                no = int(fields[FN['no']])
                if int(fields[FN['addr']]) != 7:
                    if no in numbers:
                        values.append(value.strip())
                else:
                    if no in numbers2:
                        value = float(value)
                        if no == 1:
                            value = int(value * 1000.0) # MWh in kWh
                        elif no == 2:
                            value = int(value * 1000.0) # m^3 in l
                        elif no == 3:
                            value *= 1000.0 # m^3/h in l/h
                        elif no == 4:
                            value *= 1000.0 # kW in W
                        elif no == 7:
                            value /= 1000.0 # mK in K
                        values.append(str(value).strip())
            cmd = ("rrdtool update /var/lib/kkh/%s.rrd %s:" % (address, timestamp)) + ":".join(values)
    #        print cmd
            os.system(cmd)
    
    file.close()

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •