Ein Newbie hat ne Menge Fragen ...

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
lakeck
User
Beiträge: 25
Registriert: Dienstag 20. April 2004, 16:19

Hallo zusammen !!

Ich habe eine ziehmlich komplexe Aufgabe, die ich normalerweise
unter Unix mit der Shell, AWK und diff lösen würde.

Nun möchte ich das Ganze aber gerne in Python realisieren.
Bin aber noch totaler Newbie in Python und bräuchte ein
paar Tipps (Stichworte) von euch Cracks, wo ich das nachlesen kann ..

1. per FTP ca. 200 Files von einer AIX-Buechse holen.
Files sind alle fortlaufend benannt z.B. FILE.02.0001...
FILE.02.0002...
Könnte ich mit Python-FTP hier mit Wildcars arbeiten
(vergleichbar: mget FILE.02.*) ??

2. Dann alle FILE.02.* konkatinieren (cat FILE.02.* >> FILE1)

3. Nach diesem Schema eine 2. FTP-Session und alle Files holen,
die FILE.03.* heissen .. cat FILE.03.* >> FILE2

4. In diesen beiden Files interessiert mich nur ein bestimmer
Substring (AWK: if substr($0,50,5) == 12345 > AUSGABE
(Das File hat ca. 15000 Zeilen !)
Diese Ausgabe der Substrings will ich mit FILE2 vergleichen,
(substr($0,50,5) ob dort auch verhanden, sonst >AUSGABE (diff).


Für jede Hilfe sehr dankbar !!
Lakeck
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi lakeck. Das ganze geht bestimmt mit Python, wenngleich du nicht unbedingt mit sowenigen Befehlen wie unter der Shell auskommst. Aber da werden ja schon fertige Programme nur gefüttert :wink:

zu 1.) Python bietet das Modul ftplib. Mit dem kannst du dich verbinden und dann die Dateien in einem Verzeichniss auslesen. Angenommen, ftp sei ein FTP-Verbindung (Instanz von ftplib.FTP), dann kannst du ganz einfach mit fnmatch ein Filter drüber laufen lassen:

Code: Alles auswählen

import fnmatch
filelist=fnmatch.filter(ftp.nlst(),"FILE.02.*")
Das runterladen der einzelnen Dateien sollte dann mit einer for-Schleife ein leichtes sein .

zu 2.) Das ist ebenfalls leicht. Die Dateinamen stehen ja noch in der Liste, also alle hintereinander binär öffnen lassen und zusammen in eine Datei schreiben.

Code: Alles auswählen

file1=file("FILE1","wb")
for name in filelist:
    f=file(name,"rb")
    file1.write(f.read())
    f.close()
file1.close()
zu 3.) einfach abgeändert 1. und 2. verweden... sind halt nur die Namen zu ändern...

zu 4.) tja.... sicher machbar, aber hier fehlen mir die Unixkenntnisse. Bitte beschreib für mich nochmal genauer, was hier gemacht weden soll bzw. was substr(...), AKW und diff machen.

Milan
Zuletzt geändert von Milan am Freitag 4. März 2005, 12:01, insgesamt 1-mal geändert.
lakeck
User
Beiträge: 25
Registriert: Dienstag 20. April 2004, 16:19

Meine Güte, nur 20 Minuten vergangen und schon eine Antwort !!!

Also, etwas detailierter.
Wenn ich die beiden Files habe, dann will ich einen Abschnitt einer
jeden Zeile auslesen (substr($0,50,5) soll heissen:
"Guck in jeder Zeile ab Position 50 , 5 Zeichen lang, ob dieser String
"12345" entspricht.

Vergleiche diesen Substring mit FILE2, ob er dort auch vorkommt.
Wenn nicht > Gib ihn aus !

Anmerkung an Milan:
Meine IP stimmt, OS auch, aber mit dem "Browser" liegst du daneben !!

Gruss
Lakeck
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Alles klar, nix einfacher als das :wink: . Dann könntest du natürlich file1 und file2 auch gleich mit "w+b" statt "wb" öffnen. Das erlaubt dir dann, mit file1.seek(0) gleich wieder zum Anfang zu gehen. Dann musst du die Datei zwischendurch nicht schließen und noch mal neu öffnen (erscheint mir besser/sicherer zu sein). Und dann gehts weiter:

Code: Alles auswählen

for line in file1:
    if line[50:55]=="12345":
        print line[50:55]#tue das, was du willst...
ganz klar ist mir aber noch nicht, wie mit file2 vergleichen werden soll... soll der Substring in der selben Zeile nicht vorkommen, oder nur im ganzem file nicht?

Milan

ps.: ich kann per CGI nur HTTP_USER_AGENT auslesen, was sich ja beliebig fälschen lassen lässt (man denke an Opera, mit dem z.B. ich surfe)...
Zuletzt geändert von Milan am Sonntag 16. Mai 2004, 18:26, insgesamt 1-mal geändert.
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Bei nochmaligen durchlesen fällts einem dann gleich auf. Ich glaube jedenfalls jetzt zu wissen, wie verglichen werden soll :wink: (jaja, die einfachen Dinge sinds): erst in file1 schauen, ob dort der Substring == "12345" ist. Falls dies gegeben ist, soll er in file2 schauen, ob er (der Substring) das da auch ist und falls er dort nicht "12345" ist, dann soll er ausgegeben werden. Dabei ist die Zeilennummer, in der verglichen wird in beiden files identisch. Richtig so? Mich hat erst verwirrt, dass du ganz oben zweimal was ausgeben wolltest, aber weiter unten nur einmal...

Code: Alles auswählen

from itertools import izip
for line1,line2 in izip(file1,file2):
    if line1[50:55]=="12345" and line2[50:55]!="12345":
        print line1
Ist also etwas ähnlich wie oben, nur mit Iteratoren abgewandelt, damit ich bequem über beide Dateien gleichzeitig iterieren kann. Falls das nicht die Lösung sein sollte, dürften das aber genug Stichworte gewesen sein, oder?

mfg Milan
Zuletzt geändert von Milan am Sonntag 16. Mai 2004, 18:29, insgesamt 1-mal geändert.
lakeck
User
Beiträge: 25
Registriert: Dienstag 20. April 2004, 16:19

... da hast du wahrlich recht !! Es sind genug Stichworte !!
"intertools, izip ... OHA !! Und dann erstmal schauen, wie die
Syntax für den FTP sind ....

Da kann ich mir erstmal die Zähne dran ausbeissen !!
Kann das zuhause leider nicht testen, ich denke da werden
von meiner Seite in den nächsten Tagen noch einige
Fragen kommen ... :-))

Aber erstmal recht herzlichen Dank für die schnelle Hilfe !!

Gruss
Lakeck
(P.S. surfe auch mit Opera)
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Zuerst einmal: es heißt itertools ( :wink: ) und das kommt daher, das da viele in C optimierte Funktionen gespeichert sind, die Iteratoren zurückgeben. So gibt z.B. zip([1,2],("a","b")) die Liste [(1, 'a'), (2, 'b')] zurück, über die du in einer for-Schleife iterieren kannst. izip steht für sowas wie iteratives Zip und gibt direkt einen Iterator über die Elemente zurück. Damit werden die Elemente immer nur just-in-time errechnet und das spaart Speicher (und Geschwindigkeit auch, da in C geschrieben). Aber dazu müsstest du mehr über Iteratoren und Generatoren lesen, eine große Stärke Pythons (Stichwort "yield").

Und hier ein kleines FTP-Beispiel:

Code: Alles auswählen

import ftplib,fnmatch
ftp=ftplib.FTP("ftpserver.de","loginname","passwort")
filelist=fnmatch.filer(ftp.nlst("Verzeichniss"),"FILE.02.*")
for filename in filelist:
    ftp.retrbinary("RETR %s"%filename,file(filename,"wb").write)
ftp.quit()
Und wieder ein paar Stichwörter mehr :wink:
Antworten