Frage

kann also sagen, ich bin mit Python ftplib eine Liste von Log-Dateien von einem FTP-Server abzurufen. Wie würde ich diese Liste von Dateien analysiert nur die Dateinamen (die letzte Spalte) in einer Liste zu bekommen? Siehe den Link oben zum Beispiel ausgegeben.

War es hilfreich?

Lösung

retrlines Verwendung von () ist wahrscheinlich nicht die beste Idee, da, da er druckt nur auf die Konsole und so würden Sie knifflige Dinge tun müssen, um auch in dieser Ausgabe zu erhalten. Eine wahrscheinlich bessere Wette wäre, die NLST () Methode zu verwenden, die genau zurückgibt, was Sie wollen. Eine Liste der Dateinamen

Andere Tipps

Die beste Antwort

Sie möchten ftp.nlst() verwenden, anstatt ftp.retrlines(). Es wird Ihnen genau das, was Sie wollen.

Wenn Sie nicht, lesen Sie die folgenden:

Generatoren für den Sysadmin Prozesse

In seiner berühmt gewordenen Kritik, Generator Tricks für Systeme Programmierer Einführung , David M. Beazley gibt viel receipes auf diese Art von Daten Problem mit wuick und wieder verwendbaren Code zu beantworten.

z:

# empty list that will receive all the log entry
log = [] 
# we pass a callback function bypass the print_line that would be called by retrlines
# we do that only because we cannot use something better than retrlines
ftp.retrlines('LIST', callback=log.append)
# we use rsplit because it more efficient in our case if we have a big file
files = (line.rsplit(None, 1)[1] for line in log)
# get you file list
files_list = list(files)

Warum gehen wir nicht sofort die Liste generieren?

Nun, es ist, weil es auf diese Weise Angebot machen Sie viel Flexibilität: Sie können beliebige Zwischen Generator anwenden können Dateien zu filtern, bevor es in files_list drehen: es ist wie Rohr, fügen Sie eine Zeile, fügen Sie einen Prozess ohne Überhitzung (da es Generatoren ). Und wenn Sie loswerden off retrlines bekommen, ist es immer noch funktionieren, es ist noch besser, weil Sie die Liste nicht speichern, selbst einmal.

EDIT:. Na ja, ich den Kommentar auf die andere Antwort zu lesen, und es sagt, dass dies nicht funktionieren wird, wenn es einen Raum im Namen ist

Cool, wird dies veranschaulichen, warum diese Methode praktisch ist. Wenn Sie etwas in den Prozess ändern möchten, ändern Sie einfach eine Linie. Swap:

files = (line.rsplit(None, 1)[1] for line in log)

und

# join split the line, get all the item from the field 8 then join them
files = (' '.join(line.split()[8:]) for line in log)

Ok, das kann nicht offensichtlich sein, hier, aber für großen Batch-Prozess-Skripte, es ist schön: -)

Und ein etwas weniger optimale Methode, durch die Art und Weise, wenn Sie () aus irgendeinem Grund mit retrlines stecken, ist eine Funktion als zweites Argument an retrlines () übergeben; es wird für jedes Element in der Liste aufgerufen werden. So etwas wie diese (vorausgesetzt, Sie ein FTP-Objekt mit dem Namen ‚ftp‘) würde auch funktionieren:

filenames = []
ftp.retrlines('LIST', lambda line: filenames.append(line.split()[-1]))

Die Liste ‚Dateinamen‘ wird dann eine Liste der Dateinamen sein.

Gibt es einen Grund, warum ftplib.FTP.nlst () wird nicht für Sie arbeiten? Ich habe gerade überprüft, und es gibt nur die Namen der Dateien in einem bestimmten Verzeichnis.

Da alle Dateinamen in der Ausgabe in der gleichen Spalte beginnt, alles, was Sie tun müssen, ist die Position des Punktes auf der ersten Zeile erhalten:

  

drwxrwsr-x 5 ftp-usr pdmaint 1536 Mar 20 09:48 .

schneidet dann die Dateinamen aus den anderen Zeilen mit der Position dieses Punktes als der Startindex.

Da der Punkt das letzte Zeichen auf der Linie ist, können Sie die Länge der Linie minus 1 als Index verwenden. So ist der endgültige Code ist so etwas wie folgt aus:

lines = ftp.retrlines('LIST')
lines = lines.split("\n") # This should split the string into an array of lines

filename_index = len(lines[0]) - 1
files = []

for line in lines:
    files.append(line[filename_index:])

Wenn der FTP-Server des MLSD-Befehl unterstützt, dann lesen Sie den Abschnitt „Einzel Verzeichnis Fall“ von dass Antwort.

Verwenden Sie eine Instanz (sagen ftpd) der FTPDirectory Klasse, ruft seine .getdata Methode mit angeschlossener ftplib.FTP Instanz in den richtigen Ordnern, dann können Sie:

directory_filenames= [ftpfile.name for ftpfile in ftpd.files]

Ich glaube, es sollte für Sie arbeiten.

file_name_list = [' '.join(each_file.split()).split()[-1] for each_file_detail in file_list_from_log]

NOTES -

  1. Hier mache ich eine Annahme, dass Sie die Daten in das Programm (als Liste) wollen, nicht auf der Konsole.

  2. each_file_detail ist jede Zeile, die durch das Programm erzeugt wird.

  3. ‘‘ .join (each_file.split ())

Um mehrere Räume, die durch 1 Leerzeichen ersetzt werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top