python anfänger - logfile auswerten

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.
BlackJack

Funktioniert aber nicht weil Zeile 10 mit einem `TypError` aussteigt: "'NoneType' object is not iterable".

Es wäre aber sowieso intelligenter die IDs in einem `dict` oder `collections.defaultdict` beim Einlesen zu zählen, als für jede ID die ganze Liste von vorne bis hinten zum Zählen zu durchlaufen.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Stimmt, das kommt davon wenn mans knackig halten will :( Gleich mal berichtigt ;)
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

gibt es hierfür eventuell auch noch ein kleines Beispiel?
Mit dict hab ich noch nichts getestet.
Welchen Vorteil hat denn das?
Benutzeravatar
jonas
User
Beiträge: 156
Registriert: Dienstag 9. September 2008, 21:03

Ein Dictionary könntest du vorher mit Usern und ID's füttern und dann würdest du z.B. die ID als Schlüssel benutzen um den jeweiligen User zu
finden (geht natürlich nur wenn du weißt, welche User du erwartest :wink: )

Das könnte folgendermaßen aussehen:

Code: Alles auswählen

userdict = {123:"Hans", 231:"Dieter", 464:"Gisela"} # usw...

ID = [123, 231, 464]

# Dann brauchst du hinterher nur noch so was
# wie:
for i in ID:
    print i, userdict[i]
Deine Ausgabe wäre dann z.B:

Code: Alles auswählen

123 Hans
231 Dieter
464 Gisela
MfG Jonas :wink:
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Hmm ... Jonas `ID' ist einfacher über `userdict.keys()' zu konstruieren ;) und über Dictionaries kann man direkt iterieren (oder auch über die Listen, die Methoden wie keys bereitstellen)

Zu dem Grundproblem .. wenn du die Einträge durch `set' jagst, dann gibt es keine doppelten oder mehrere Einträge und somit keine die man zählen kann ;)
BlackJack

@krischeu: Der Vorteil das in einem `dict` gleich beim Einlesen zu zählen ist, das man kein Programm mit quadratischer Laufzeit bekommt, sondern eines das in linearer Zeit läuft. Jeweils in Bezug auf die Zeilenanzahl in der Log-Datei gesehen.
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Hallo,
es ist soweit gediehen und funktionabel.
Zählen geht jetzt auch. Ausgabe ist z.B.
1120 24
1176 13
1021 58
1009 94
1013 44
Aber wie kann ich os.system('ypcat passwd') zum weiterverabeiten in eine sequenz schreiben (den output ntürlich)?
Es sollte schon mit ypcat funktionieren, wenn Benutzer gelöscht werden oder dazu kommen, will ich nicht jedes mal die Scripte anpassen.


Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import string 
import os 


try:
 # FILE oeffen und in eine SEQUENZ / ARRAY schreiben
 logfile = file("/var/log/auswertung/logfile.txt", "r")			# Oeffnen des Files
 logfileinhalt = [line.rstrip('\n') for line in logfile.readlines()]	# einlesen des Fileinhaltes
 inhalt_logfile = []							# Leere Sequenz / Array erstellen um dann das LOG-File hierrein zu speichern
 for line in logfileinhalt:
   a = line
   inhalt_logfile.append(a)

finally:
 logfile.close()							# Datei schliessen



# ARRAY / Sequenz sortieren
inhalt_logfile.sort()						        # Sortieren des Inhaltes der Sequenz/Array

# doppelte Eintraege loeschen und STRINGS zaehlen
userID = list(set(inhalt_logfile))				        # Neue Sequenz/Array mit allen Eintraegen aus der originalen Sequenz
#     								        # ABER ohne doppelte Eintraege
for checkuserID in userID:
 print checkuserID,
 print inhalt_logfile.count(checkuserID)

# userID einem Benutzernamen zuordnen
# 
os.system('ypcat passwd')						# Ausgabe von ypcat in die Variable var (STRING)
# variable = [line.rstrip('\n') for line in os.system('ypcat passwd').readlines()]
#array=[]								# leeres Array erstellen
#for zeile in var:
# spalte=zeile.split()
# array.append(zeile)
# print array[1,1]
lunar

Lies die Doku zum subprocess-Modul und vergiss am besten, dass es os.system() überhaupt gibt.
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hi.
Mal eine Frage zu cofi's Code.
Wieso schreibt er das Öffnen und Auslesen in einen try-Block, wenn dieser eh ohne except endet? Was bringt es, dass finally einzubauen? Käme doch auf's selbe Hinaus, es gänzlich ohne zu belassen, oder nicht?

~ Chris
Grüßle.
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Also,
das hab ich mir mal angeschaut:
http://pydoc.org/2.5.1/subprocess.html

das hab ich dann mal ausprobiert, weil es meinem Wunsch am naechsten kam. (import subprocess oben reingeschrieben!)

Code: Alles auswählen

Replacing shell pipe line
-------------------------
output=`dmesg | grep hda`
==>
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]
Allerdings bekomme ich immer noch eine Fehlermeldung:
Traceback (most recent call last):
File "./filter4.py", line 58, in <module>
p1 = Popen(["dmesg"], stdout=PIPE)
NameError: name 'Popen' is not defined

Ist ja hartes Brot die Ausgabe aus einer Shell weiter zu verarbeiten ...[/code]
lunar

Das ist jetzt aber Grundlagenwissen. Es sollte eigentlich klar sein, dass du die entsprechenden Attribute vorher aus "subprocess" importieren muss.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

@chrisber Es gibt kein finally ohne try ;) Und da Dateien auf jedenfall geschlossen werden sollten - ungeachtet von Exceptions usw. -, sollte man sie in einem try-Block öffnen und sie im finally-Block schliessen.

Mit 2.6 und dem with-Statement ist das aber für den meisten Code ein alter Hut.
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

krischeu hat geschrieben:das hab ich dann mal ausprobiert, weil es meinem Wunsch am naechsten kam. (import subprocess oben reingeschrieben!)
Schreib mal lieber

Code: Alles auswählen

from subprocess import PIPE, Popen
rein. ;)
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Jup,
das hat gefehlt.

Jetzt funktioniert das schon mal mit dem einlesen deer Ausgabe eines Shell-Befehls.
Die Ausgabe von ypcat passwd liegt nun im array. Jeweils als einzelne Buchstaben.
['V', 'M', '0', '0', '1', '$', ':', 'x', ':', '3', '0', '2', '8', ':', '1', '0', '2', '0', '0', ':', 'N', 'T', 'M', 'a', 'c', 'h', 'i', 'n', 'e', ':', '/', 'n', 'e', 't', '/', 'h', 'o', 'm', 'e', '/', 'V', 'M', '0', '0', '1', '$', ':', '/', 'b', 'i', 'n', '/', 't', 'c', 's', 'h', '\n',
...
usw.
Aus dem ganzen Wust sollte nun unter rühren vm001 3028 10200 gemacht werden.
ich dachte da grundsätzlich an sowas wie:

Code: Alles auswählen

array=[]
zeile=''#ein leerer string
for buchstabe in ypcatpasswdarray:
   if buchstabe == '\n':
      zeile=zeile+buchstabe #zeielnstring zusammensetzen
      array.append(zeile)
      zeile='' #zeilen inhalte  loeschen
   else:
      zeile.append(buchstabe)
Gibt es da was eleganteres?
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wie hast du denn das geschafft? Normalerweise müsste die Ausgabe ein String und keine Liste sein. Zum Zusammenfügen:

Code: Alles auswählen

In [11]: out = ['V', 'M', '0', '0', '1', '$', ':', 'x', ':', '3', '0', '2', '8', ':', '1', '0', '2', '0', '0', ':', 'N', 'T', 'M', 'a', 'c', 'h', 'i', 'n', 'e', ':', '/', 'n', 'e', 't', '/', 'h', 'o', 'm', 'e', '/', 'V', 'M', '0', '0', '1', '$', ':', '/', 'b', 'i', 'n', '/', 't', 'c', 's', 'h', '\n', 'b', 'l', 'a', '\n', 'b', 'l', 'u', 'p', 'p']

In [12]: ''.join(out)
Out[12]: 'VM001$:x:3028:10200:NTMachine:/net/home/VM001$:/bin/tcsh\nbla\nblupp'

In [13]: print ''.join(out)
VM001$:x:3028:10200:NTMachine:/net/home/VM001$:/bin/tcsh
bla
blupp
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Hallo,
hier der aktuelle Stand:

Die Frage ist nun, wie kann ich die Ausgabe die so aussehen kann ( 3 Möglichkeiten) separieren und in Array oder String bringen?

USERDATENSATZ: heinz:x:1121:10101:Heinz Krischeu:/net/home/heinz:/bin/bash
TESTTEMP heinz:x:1121:10101:Heinz Krischeu:/net/home/heinz:/bin/bash
YPCATPASSWDARRAY ['h', 'e', 'i', 'n', 'z', ':', 'x', ':', '1', '1', '2', '1', ':', '1', '0', '1', '0', '1', ':', 'H', 'e', 'i', 'n', 'z', ' ', 'K', 'r', 'i', 's', 'c', 'h', 'e', 'u', ':', '/', 'n', 'e', 't', '/', 'h', 'o', 'm', 'e', '/', 'h', 'e', 'i', 'n', 'z', ':', '/', 'b', 'i', 'n', '/', 'b', 'a', 's', 'h', '\n']

Gibt es sowas wie find bis zum ":" --> dann nächtes Feld ...
Die Felder entsprechen denen aus userlogin,userID, GruppenID, etc.



Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import string 
import os 
import subprocess
from subprocess import PIPE, Popen
try:
 # FILE oeffen und in eine SEQUENZ / ARRAY schreiben
 logfile = file("/var/log/auswertung/logfile.txt", "r")			# Oeffnen des Files
 logfileinhalt = [line.rstrip('\n') for line in logfile.readlines()]	# einlesen des Fileinhaltes
 inhalt_logfile = []							# Leere Sequenz / Array erstellen um dann das LOG-File hierrein zu speichern
 for line in logfileinhalt:
   a = line
   inhalt_logfile.append(a)

finally:
 logfile.close()							# Datei schliessen



# ARRAY / Sequenz sortieren
inhalt_logfile.sort()						        # Sortieren des Inhaltes der Sequenz/Array

# doppelte Eintraege loeschen und STRINGS zaehlen
userID = list(set(inhalt_logfile))				        # Neue Sequenz/Array mit allen Eintraegen aus der originalen Sequenz
#     								        # ABER ohne doppelte Eintraege
for checkuserID in userID:
 print checkuserID,
 print inhalt_logfile.count(checkuserID)

# userID einem Benutzernamen zuordnen					# Benoetigte IMPORTS sind:
#									# "import subprocess"
#									# "from subprocess import PIPE, Popen"
ypcatpasswdarray=[]							# leeres Array erstellen
ypcatpasswdshell = Popen(["ypcat", "passwd"], stdout=PIPE)		# Ausgabe von "ypcat passwd" wird gepiped 
output = ypcatpasswdshell.communicate()[0]				# Die "0" gibt stdout zurück (holt sich die Ausgabe der PIPE)
									# Die "1" gibt stderr zurück
print output
# Ausgabe von ypcat passwd wird in das Array geleitet
for line in output:							# Nimmt den STRING "output" und leitet alles in das Array 
	a = line
	ypcatpasswdarray.append(a)
	
# print ypcatpasswdarray[5]						# Zaehlt 6 Zeichen (von "0" bis "5")
# print ypcatpasswdarray						# Ausgabe des Arrays

# 
# Aus dem Array ypcatpasswdarray wird tmparray 				# Aus einzelnen Buchstaben wird ein Datensatz
# print tmparray[0] gibt einen einzelnen Datensatz aus			# Hier den ersten
tmpstring=[]
passwdzeile=''								#ein leerer string
for einzelnerbuchstabe in ypcatpasswdarray:
   if einzelnerbuchstabe == '\n':
      passwdzeile=passwdzeile+einzelnerbuchstabe 			#zeilenstring zusammensetzen
      tmpstring.append(passwdzeile)
      passwdzeile='' 							#zeileninhalte  loeschen
   else:
      passwdzeile+=(einzelnerbuchstabe)


testtemp = ''.join(ypcatpasswdarray)


print tmpstring[2:3]
print testtemp[112:130]
print ypcatpasswdarray[112:130]
[/code]
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Bau es zu einem langen String zusammen (siehe snafu) und wende .split(":") auf den String an. Das gibt eine Liste von Strings zurück.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Warum so kompliziert?

Dieses ``YPCATPASSWDARRAY`` ist so nützlich wie das fünfte Rad am Wagen. Da würde man direkt den String der Ausgabe von ``ypcat`` nehmen, zeilenweise iterieren und an den Doppelpunkten splitten.
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Hallo,
ich bräuchte noch mal ein bischen hilfe.
ich habe ein array. dort gibt es diverse strings. hauptsächlich sind es entweder zahlen-strings oder buchstaben-strings.
ich bräuchte nun eine if abfrage, die testet, ob der string aus zahlen besteht oder aus buchstaben.

Code: Alles auswählen

import sys, string
import subprocess
from subprocess import PIPE, Popen
import os 
def logfile_oeffnen_und_auswerten():
    import string
    # FILE oeffen und in eine SEQUENZ / ARRAY schreiben
    logfile = file("/var/log/auswertung/logfile.txt", "r")			
    logfileinhalt = [line.rstrip('\n') for line in logfile.readlines()]	# einlesen des Fileinhaltes
    inhalt_logfile = []							# Leere Sequenz / Array erstellen um dann das LOG-File hierrein zu speichern
    for zeile in logfileinhalt:
       inhalt_logfile.append(zeile)
    logfile.close()							# Datei schliessen
    # Doppelte Eintraege loeschen 
    userID = list(set(inhalt_logfile))					# Neue Sequenz/Array mit allen Eintraegen aus der originalen Sequenz
    i=0

###                                              ###
    for i in userID:
	if isinstance ("i", int):
		print "zahl", i
	else:
		print "Buchstabe", i
###                                              ###
	
    # Ausgabe der UserID/Username und der Stundenanzahl			# ABER ohne doppelte Eintraege
    ausgewertetes_logfile_array = []
    for checkuserID in userID:
     ausgewertetes_logfile_array.append(checkuserID)
     ausgewertetes_logfile_array.append(inhalt_logfile.count(checkuserID))
    return ausgewertetes_logfile_array
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Code: Alles auswählen

'1'.isdigit()
Antworten