csv schreibt nur in jede 2 Zeile

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Basti91
User
Beiträge: 53
Registriert: Samstag 15. Dezember 2007, 11:50
Wohnort: Saarland

Hallo,
Hier ein Skript, dass eine Datei ausliest und in eine .csv Datei speichert
Das Problem ist, dass in der .csv Datei nach jeder Zeile, eine Zeile freigelassen wird.
Außerdem wüsste ich gerne, wie ich eine Spalte vorher definiere ( zu Text).

Code: Alles auswählen

import csv

def log_auslesen(dateipfad):      
    datei = open(dateipfad,"r")
    log_liste =[]
    for line in datei:
        log_liste.append(line)
        
    datei.close()
    return log_liste



def datum_auslesen(log_liste):
    log_date_list = []
    for i in range(0,len(log_liste)):
        log_date_list.append(log_liste[i][0:10])
    return log_date_list


def zeit_auslesen(log_liste):
    log_time_list = []
    for i in range(0,len(log_liste)):
        log_time_list.append(log_liste[i][12:23])
    return log_time_list
                   
def bericht_auslesen(log_liste):
    log_command_list = []
    for i in range(0,len(log_liste)):
        log_command_list.append(log_liste[i][25:])
    return log_command_list

def log2csv(logpath):
    logfile = log_auslesen(logpath)
    log_date_list= datum_auslesen(logfile)
    log_time_list= zeit_auslesen(logfile)
    log_command_list = bericht_auslesen(logfile)
    writer = csv.writer(open("test.csv","w"),delimiter=';')
    for i in range (0,len(log_date_list)):
        writer.writerow([log_date_list[i],log_time_list[i],log_command_list[i]])
    

def main():
    log2csv("test.log")


main()
print ("done")
Zuletzt geändert von Anonymous am Freitag 6. Mai 2011, 10:48, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@Basti91: In den Daten die Du einliest ist am Ende jeder Zeile Zeilenende-Zeichen. Das möchtest Du anscheinend nicht mit in den Ausgabedaten habe. Also entweder beim Einlesen entfernen, oder die `bericht_auslesen()`-Funktion anpassen.

Sonstiges: Das ``range(0,len(…))``-Konstrukt wurde ja in einem anderen Beitrag schon einmal angesprochen -- es ist unpythonisch und unnötig. Man kann über die Elemente von Listen *direkt* iterieren, ohne einen Umweg über einen Index machen zu müssen. Die `*_auslesen()`-Funktionen lassen sich zudem alle mit einer einfachen "list comprehension" ausdrücken, die zu allem Überfluss auch noch bis auf zwei literale Zahlen identisch wären. Das könnte man also auch in eine Funktion schreiben und die dann mit den Zahlen als Argumenten aufrufen.

Man könnte das Auslesen aber auch so organisieren, dass es eine Funktion gibt, die aus jeder Logzeile gleich alle drei Informationen ausliest. Dann muss man das Log nicht dreimal durchgehen. Man könnte es sich dann sogar sparen das Log am Anfang komplett einzulesen. Und wenn man dann noch die einzelnen Zeilendaten sofort in die CSV-Datei schreibt, braucht man nur Speicher für einen einzigen Log-Eintrag und die Daten können beliebig umfangreich werden, ohne dass man sich Sorgen um Arbeitsspeicher machen muss.

Datentypangaben wie `list` sollten möglichst nicht in Namen verwendet werden. Wenn man den Typ mal ändern sollte hat man entweder falsche Namen oder muss die alle anpassen.

Dateien sollte man immer explizit schliessen. Das tust Du bei der CSV-Datei nicht. Am besten verwendet man die ``with``-Anweisung.

Die Frage nach der Spaltendefinition verstehe ich nicht? Redest Du jetzt von Excel-Tabellen? In CSV gibt es keine Datentypen.
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Basti91 hat geschrieben:Hier ein Skript, dass eine Datei ausliest und in eine .csv Datei speichert
Das Problem ist, dass in der .csv Datei nach jeder Zeile, eine Zeile freigelassen wird.
Dein Programm ist unnötig kompliziert. Versuche einfacheren Code zu schreiben. Im Prinzip kann man das auf Folgendes eindampfen.

Code: Alles auswählen

import csv

def log2csv(logfile_name):
    with open(logfile_name, 'r') as logfile: 
        with open('csv_01.csv', 'wb') as csvfile:
            writer = csv.writer(csvfile, delimiter=';')
            for line in logfile:
                writer.writerow([line[0:10],
                                 line[12:23],
                                 line[25:].strip()])

if __name__ == '__main__':
    log2csv('csv_01.log')
Das ist kürzer _und_ übersichtlicher. Fehlerbehandlung sollte im Bedarfsfall noch ergänzt werden.
Benutzeravatar
Basti91
User
Beiträge: 53
Registriert: Samstag 15. Dezember 2007, 11:50
Wohnort: Saarland

@/me

Der Code sieht vielversprechend aus.
Leider bekomme ich aber eine Fehlermeldung wenn ich ihn ausführe:

Code: Alles auswählen

 line 10, in log2csv
    line[25:].strip()])
TypeError: 'str' does not support the buffer interface
Benutzeravatar
Basti91
User
Beiträge: 53
Registriert: Samstag 15. Dezember 2007, 11:50
Wohnort: Saarland

Hab den Fehler gefunden, bei open('csv_01.csv', 'wb') muss das 'wb' mit 'w' ersetzt werden.
Leider löst das noch nicht mein Leerzeilenproblem.
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Basti91 hat geschrieben:

Code: Alles auswählen

 line 10, in log2csv
    line[25:].strip()])
TypeError: 'str' does not support the buffer interface
Dann nehme ich mal an, dass du Python 3.x verwendest. Entferne das "b"-Flag bei der zu schreibenden Datei.
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Basti91 hat geschrieben:Leider löst das noch nicht mein Leerzeilenproblem.
Der writer nimmt als Zeilenendemarkierung als Default '\r\n'. Dein Anzeigeprogramm führt offensichtlich bei jedem der beiden Zeichen einen Zeilenumbruch durch. Instanziiere den writer so, dass er nur ein normales Newline verwendet.

Code: Alles auswählen

writer = csv.writer(csvfile, delimiter=';', lineterminator='\n')
Benutzeravatar
Basti91
User
Beiträge: 53
Registriert: Samstag 15. Dezember 2007, 11:50
Wohnort: Saarland

Wie oben geschrieben hab ich den Fehler gefunden.
Jedoch ist mir noch aufgefallen, dass manche Zeilen mit einem '=' beginnen.
Was kann ich den anstellen, damit Excel nun keine Funktion erwartet?
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Basti91 hat geschrieben:Jedoch ist mir noch aufgefallen, dass manche Zeilen mit einem '=' beginnen.
Was kann ich den anstellen, damit Excel nun keine Funktion erwartet?
Die Felddaten so erzeugen, wie du sie in Excel auch eingeben würdest wenn du ein Gleichheitszeichen vorne hättest: Mit einem führenden Hochkomma.
Antworten