Ordner aus .txt Name erstellen und .txt dort hin verschieben

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
MarcNAV
User
Beiträge: 52
Registriert: Freitag 16. Mai 2014, 11:39

Hab länger schon in Foren geschaut aber keine ähnliche Problemstellung gefunden.
Ich hätte gern ein Programm, dass einen beliebigen Dateibaum (Bsp.: F:/Test/X/Y/hallo.txt) durchläuft und nach .txt Dateien sucht. Dann soll es in den Dateipfad der .txt wechseln, dort einen Ordner mit gleichem Namen aber ohne Extension erstellen und die .txt dorthin verschieben.

Bsp.: ->Textdatei F:/Test/X/Y/hallo.txt
->erstelle dort "hallo" Ordner
->verschiebe test.txt in F:/Test/X/Y/hallo/hallo.txt

Probleme habe ich dabei in das jeweilige .txt Verzeichnis zu wechseln weil er mir momentan fälschlicherweise den Ordner immer in 'F:/Test' erstellt.
Ich würde das ganze aber gerne mit os.walk machen da die unterordner variabel sind. Danke für eure Hilfe schon mal.

Code: Alles auswählen

import os, sys
import shutil as st

def main():

    path = (r'F:/Test')
    for (path, dirs, files) in os.walk(path):
        for file in files:
            if file.endswith(".txt"):
            os.chdir(file)   
            folder = os.mkdir(os.path.basename(file)[:-4]) 
            st.move(file, folder)


if __name__ == '__main__':
    main()

EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

In Zeile 10 versuchst du in die Datei zu wechseln und nicht in den Ordner. Das funktioniert so natürlich nicht. Allerdings solltest du das Arbeitsverzeichnis überhaupt nicht wechseln, das kann zu sehr unangenehmen Fehler führen. Dir ist doch mittels "path" der Pfad zum Ordner gegeben, setze einfach den neuen Ordnerpfad mittesl "os.path.join" zusammen, erstelle den Pfad und dann verschiebe die Datei.

Da sind allerdings noch einige andere Dinge, welche du korrigieren solltest. "st" ist eine total nichtssagend Abkürzung für "shutil". Da weißt du doch schon übermorgen nicht mehr, was "st" eigentlich ist. Auch sind die Klammern in Zeile 6 alle überflüssig.

Ansonsten solltest du noch an den Namen arbeiten, "files" sollte besser "filenames" und "file" besser "filename" heißen. Da stecken ja keine Dateien hinter, sondern die Namen der Dateien. Zum Matchen der Dateien könntest du dir noch das fnmatch-Modul anschauen.

Die -4 in Zeile 11 solltest du auch noch loswerden, dass solltest du aus dem zu matchendem String bestimmen. Magische Zahlen im Code sind eine beliebte Fehlerquelle. Häufig ändert man eine Stelle und vergisst alle anderen davon abhängigen. Oder noch schlimmer: Die Abhängigkeiten werden so verschlungen dass du sie nicht mehr nachvollziehen kannst.
Das Leben ist wie ein Tennisball.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Probier das mal

Code: Alles auswählen

import os, sys
import shutil as st
rootPath = (r'F:/Test')
for (path, dirs, files) in os.walk(rootPath ):
    for file in files:
        if file.endswith(".txt"):
            folder = os.mkdir(os.path.join(rootPath , path, file[:-4]))
            st.move( os.path.join(rootPath , path, file) ,  folder)
a fool with a tool is still a fool, www.magben.de, YouTube
MarcNAV
User
Beiträge: 52
Registriert: Freitag 16. Mai 2014, 11:39

Danke für die schnellen Antworten! Beschäftige mich erst seit 6 Wochen mit Python, aber finde immer mehr gefallen daran.

@EyDu: gut zu wissen thx

@MagBen:
Das mit dem Ordner erstellen an der richtigen stelle funktioniert schon mal. Leider kommt Zeile 8 folgender Fehler:

TypeError, coercing to Unicode: need String or buffer, NoneType found

Ich schau mal, woran es liegen könnte.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

``os.mkdir`` liefert als Ergebnis None zurück und nicht den Pfad des erstellten Ordners.
Das Leben ist wie ein Tennisball.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@MagBen: Du hast immer noch die seltsame Abkürzung von shutil und die Klammern um den String in Deinem Beispiel und auch noch die magische -4. Deine Namen halten sich nicht an PEP8 und Dein Code landete auf Modulebene anstatt wie MacNavs Code in einer main. Deine Leerzeichensetzung ist auch weder der Norm.
BlackJack

Ungetestet:

Code: Alles auswählen

import os
import shutil


def main():
    root_path = 'F:/Test'
    extension = '.txt'
    for path, _, filenames in os.walk(root_path):
        for filename in filenames:
            if filename.endswith(extension):
                source = os.path.join(path, filename)
                target = source[:-len(extension)]
                os.mkdir(target)
                shutil.move(source, target)


if __name__ == '__main__':
    main()
MarcNAV
User
Beiträge: 52
Registriert: Freitag 16. Mai 2014, 11:39

Okay habs jetzt hinbekommen. Thx EyDu.
Das von BlackJack is n bißchen übersichtlicher und aufgeräumter aber meins tuts jetzt auch.

Code: Alles auswählen

import os, shutil



def main():

    rootPath = (r'F:/Test')
    for (path, dirs, filenames) in os.walk(rootPath):
        for filename in filenames:
            if filename.endswith(".txt"):

                fname = os.path.splitext(os.path.basename(filename))[0]
                os.mkdir(os.path.join(rootPath, path, fname))
                folder = os.path.normpath(os.path.join(rootPath, path, fname))
                shutil.move(os.path.join(rootPath , path, filename), folder)

if __name__ == '__main__':
    main()

Zuletzt geändert von MarcNAV am Mittwoch 18. Juni 2014, 12:17, insgesamt 1-mal geändert.
MarcNAV
User
Beiträge: 52
Registriert: Freitag 16. Mai 2014, 11:39

@BlackJack thx funktioniert auch;) gerade getestet

Danke für die Hilfe an alle
Antworten