Aus Ordnerinhalt txt erstellen

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.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo,
bitte nicht gleich wieder steinigen.
Ich Orientire mich an einem altem bsp, wo auch funktioniert, da kenne ich die Unterordner und den Inhalt.
Ich habe einen Ordner in dem habe ich Unterordner in jedem Unterorder sind txt Dateien, hier kenne ich den Inhalt nicht mehr.
Ich möchte eine neue txt Datei erstellen mit der Anzahl der txt Dateien und den Namen pro Unterordner.
Bsp ein Ordner Textdateien in dem haben wir dann Unterordner1, Unterordner2, Unterodner3, im Unterordner1 habe ich textdate1.txt, textdatei2.txt, dann Unterordner2 textdate2.txt, textdatei3.txt usw. Jetzt möchte ich pro Unterordner eine text Datei erstellen bsp
Unterordner1.txt
anzahl 2
textdate1.txt
textdatei2.txt

I Moment komme ich ums verrecken nicht weiter, und verstehe auch nicht wo mein Fehler ist, was mache ich falsch.
Von Gedanken her müsste es passen, tut es aber leider nicht, ich bekomme die neuen Textfiles.txt erstellt aber in jedem text file steht mir der Inhalt aus allen Unterordner. Vielleicht hat einer Zeit Interesse Lust mich da in die richtige Richtung zu schupsen, damit ich meinen Fehler finde.
Wahrscheinlich kann ich mir auch eine Funktion sparen.
Es kann sein das einrücken nicht stimmt, aber wie gesagt es tut aber nicht so wie es soll.
Vilen Dank im Voraus.

Hier mein versuch.

Code: Alles auswählen

#!/usr/bin/python3

from pathlib import Path
import os

#in diesem Textfile sind alle Unterordner aufgelistet, an der letzten stelle ist eine nr, mit dieser Nummer fangen dann alle Textfiles an, #unterschiedlich für jeden Unterordner.
def suchetxt():
    nr = []
    filename = open("/home/a/mein_textfile/mein.txt", "r")
    daten = filename.read()
    filename.close()
    liste = daten.split()
    for i in range(len(liste)):
        woerter = liste[i].split("_")
        nr = woerter[-1]
        matchnr.append(nr)
    return matchnr

path = Path("/home/a/meinordner/mein_backup")
def find_files(path, patterns):
    return [p for p in path.rglob('**/*')
        if any(p.match(pattern) for pattern in patterns)
    ]

line_files = []
def nesto():
    line_f = []
    a = suchetxt()
    for elem in a:
        line_files = [elem+"*.txt"]
        #print (line_files)
        with open("/home/a/mein_textfile/mein.txt", "r") as output:
            for line in output:
                line = line.strip()
                #hier stimmt es mit print bekomme ich genau das was ich will
                #print (line)
                for line_file in find_files(path, line_files):
                    line_f.append(line_file.name)
                    #hier passt es auch mit print
                    #print (line_f, "jdglkahdjglkahjdlkghadlkgfhaelhg")
                    
                for line_file in find_files(path, line_files):
        	    line_f.append(line_file.name)
        	    #hier passt es mit dem print nicht mehr   
		    print (line_f)
		    
                with open("/home/a/meine_textfile/mails/"+line+"_intern.txt", "w", encoding= "utf8") as output:
                    output.write(f"Anzahl TXT's: {len(line_f)}\n\n")
                    names = '\n'.join(line_f)
                    output.write(f"Abgeholte TXT's: \n\n{names}\n")
nesto()

Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ganja: Die zwei Hauptgründe warum ich das nach kurzem überfliegen nicht lesen möchte: Funktionen und globale Variablen auf Modulebene vermischt, und ein paar Namen die sofort ins Auge gestochen sind: `dateiname` für ein *Datei*-Objekt, `line_f`, `a` und ``for elem in a:``, und das öffnen einer Textdatei zum lesen die dann völlig dem entgegen `output` heisst. Wenn man verwirrende Namen verwendet, bekommt man verwirrenden Code.

Edit: Ach ja, die Funktionsnamen `suchetext()` und `nesto()`. WTF‽
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

@__blackjack__, Ok, leider kann ich die richtigen Namen nicht verwenden, aber ich gebe dir recht, a im path und a=funktion. Wie kann ich es ändern muss ich nochmal posten, oder gibt es eine Möglichkeit den vorherigen Beitrag zu bearbeiten?
Danke
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst nochmal posten.
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Dateien öffnet man in einem with-Statement. `filename` für ein File-Objekt ist falsch.
Dem `open` fehlt ein `encoding`. Über einen Index iteriert man nicht.
Du definierst eine Liste `nr` benutzt aber dann `matchnr`, was gar nicht definiert ist.
In `matchnr` speicherst Du nur die Nummer, und in `nesto` gehst Du nochmal die selbe Datei durch, um dann alle Zeilen durchzugehen und diese mit allen Nummern zu kombinieren.
`find_files` nimmt patterns, was aber immer nur ein Element enthält, das man auch gleich in rglob einbauen könnte. Die Funktion hat also eine Flexibilität, die gar nicht gebraucht wird, das Programm aber deutlich komplizierter macht. Fang so einfach an, wie möglich und erweitere erst, wenn Du die Funktionalität wirklich brauchst.
In `nesto` mischst Du dann Tabs und Spaces, was man niemals machen darf. So weiß ich nicht, was Du Dir mit der Einrückung wirklich gedacht hast.
Die for-Schleifen über `find_files` sind überflüssig, da Du nur eine Liste in eine andere Liste kopierst.
Im Einleitenden Text schreibst Du irgendwas von Unterordnern, im Code findet sich aber keine Unterordner mehr, sondern Dateien, die mit einem Präfix anfangen.
Was gilt den nun?

Beim Kommentar `#hier passt es mit dem print nicht mehr`, was passt konkret nicht? Wie sieht Deine Verzeichnisstruktur aus, was bekommst Du, und was hättest Du statt dessen?

Erkläre also erst einmal, was Dein wirkliches Problem ist, dann kannst Du das Problem in einzelne Unterprobleme aufteilen und für jedes eine kleine einfache Funktion schreiben.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Danke @ __deets__, Danke @Sirius3,
ich versuche es nochmal morgen alleine, ich denke ich muss aus den loops raus.
Ich habe es in kleine Funktionen unterteilt, hier beim post bin ich dann durcheinander gekommen mit Tabs und Spaces und den Namen.
Eigentlich ist es ganz einfach, ich lese im Ordner Unterordner aus, schreibe die Namen der Unterordner (jeder Unterordner hat eine eindeutige Nr am ende) in ein Textfile, in jedem Unterordner habe ich Textfiles alle fangen mit der Nr aus dem Namen des Ordners an.
Als einzelne scripte funktioniert alles, jetzt habe ich viele Parameter in die DB eingepflegt, und an statt 3 scripte laufen zu lassen möchte ich es mit einem, bin eigentlich so weit, nur das hier fehlt mir noch.
Habe auch gedacht wenn ich es fertig habe und es läuft, wollte ich das ganze script hier im Forum posten, davon erhoffe ich mir, das ihr mir dann sagt was man besser machen kann, was mann eventuell kürzen kann tipps etc.
Aber erstmal möchte ich es so fertig stellen, man kann nur Erfahrung sammeln in dem man sich Projekte vorstellt und die dann umsetzt, das man immer etwas verbessern kann dessen bin ich mir bewusst, mit wenig Erfahrung macht man manchmal Sachen doppelt.

jetzt möchte ich Textfile erstellen, in dem Anzahl und die Namen der Textfiles pro Ordner.
z.b.
Ordner1 Ordner2
1_textfile1.txt. 2_textfile3.txt
1textfile2.txt. 2_textfile1.txt

Ich möchte in neuen Textfiles folgendes haben nur als text für jeden Ordner.
Ordner1.txt mit Inhalt
Anzahl 2
1_textfile1.txt
1_textfile2.txt
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo zusammen,
dann versuche ich es nochmal, heute ist mir eingefallen ich habe eine csv mit allen Textfiles aus allen Ordnern. Habe es dann versucht mit der csv, leider nicht geschafft.
Ich denke vieles kann man einfacher erstellen, mir fehlt leider immer noch die Erfahrung.
Ich hoffe einer hat Zeit und Lust, ich alleine komme da nicht weiter.
Bessere Namen sin mir nicht eingefallen.
Vielen Dank im Voraus.

Code: Alles auswählen

#!/usr/bin/python3

from pathlib import Path
import os

""" Hier versuche ich nur die Nummer aus dem Ordnernamen mitzunehmen, passt auch habe eine liste mit allen Nummern aller Ordner Ich denke diese Funktion ist überflüssig
"""
def suchnr():
    nr = []
    filename = open("/home/ja/mein_textfile/mein.txt", "r")
    daten = filename.read()
    filename.close()
    liste = daten.split()
    for i in range(len(liste)):
        woerter = liste[i].split("_")
        wort = woerter[-1]
        nr.append(wort)
    return nr

path = Path("/home/ja/meinordner/mein_backup")
def find_files(path, patterns):
    return [p for p in path.rglob('**/*')
        if any(p.match(pattern) for pattern in patterns)
    ]
    
def nestocare():
    line_f = []
    line_files =[]
    line_file = []
    nr = suchnr()
    
    for elem in nr:
        line_file1 = elem
        line_file.append(str(line_file1))
    print (line_file, " nummer")
    with open("/home/ja/meinordner/meintextfile.txt", "r") as output:
        for line in output:
            line = line.strip()
            line_files.append(line)
    #print (line_files, " unterordner")

    with open("/home/ja/meinordner/meinecsv.csv") as csvdatei:
        csv_reader_object = csv.reader(csvdatei)
        for row in csv_reader_object:
            #print (row)
            """ hier komme ich nicht weiter ich kann alle textfiles aus allen Ordnern ausgeben mit print,
                 aber die dann zu sortieren klappt nicht, neue Textfiles zu erstellen pro Ordner mit dem Inhalt des Ordners
            """  
        
        ## hier kann ich alle textfiles.txt erstellen als Name der Ordnername
        #for ordner in line_files:
        #    #print (ordner)
        #    ordner = str(ordner)
        #    with open("/home/ja/meinordner/"+ordner+"_intern.txt", "w", encoding= "utf8") as output:
        #        output.write(f"{aktuell}\n\n\n")
        #        output.write(f"Anzahl TXT's: {len(file2)}\n\n")
        #        names = '\n'.join(file2)
        #        output.write(f"Abgeholte TXT's: \n\n{names}\n")

nestocare()
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Ich nehme an hier kann mir keiner helfen, entweder versteht ihr mein Problem nicht, wahrscheinlich habe ich es so schlecht erklärt und mein Code ist sh..
Möglich das es gar nicht geht, ich weiß es nicht.
Dann frage ich noch mal:
Ich will Inhalt von mehreren Unterordner aus einem Ordner, in mehrere .txt Dateien speichern, der Name jeder der .txt soll wie der Unterordner heißen, der Inhalt des Unterordners soll in der entsprechenden .txt Datei sein.
Ich kenne die Unterordner nicht ich kenne nur den ersten Ordner.
ich bekomme es hin alle Dateien mit Pfad zu sehen mit dem print. Ich bekomme es nicht hin eine schleife zu schreiben die mir, Dateien pro Unterordner schreibt.
Ich habe gedacht es wäre einfach habe aber irgendwo einen Riesen Gedanken Fehler, for schleife und dann if Pfad im Ergebnis aus for schleife, oder nicht!
Wenn mir einer hier bei helfen kann, wäre ich ihm sehr Dankbar, und sollte es zu einem Treffen hier mit den Leuten aus Forum geben, gehen mindestens 3 Runden auf mich :D aber nur ab 40% Getränk.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Ich habe es.
nicht so wie ich es wollte aber es tut. Vielleicht kann einer auch mal den anderen einfacheren weg posten, ich poste meinen weg vielleicht kann es jemand brauchen, auch wenn es nicht perfekt ist.
Ich Danke euch für jeden Tipp, jede Kritik, jeden bsp etc

Code: Alles auswählen

def test1():
    wo = "/home/ja/meinordner/mein_backup"
    wohin = "/home/ja/meinordner/samonestozatest"
    for root, dirs, files in os.walk(wo):
        for dr in dirs:
            dr = os.path.join(root, dr)
            d = dr.split(os.sep)
            da = d[-1]
            print (da)
            open(os.path.join(wohin, da+".txt"), "wt").write(
                ",".join(f for f in os.listdir(dr) if f != "list.txt")
            )
test1()
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

`dr`, `d`, `da`? Alles wirklich schlechte Variablennamen, weil niemand raten kann, für was jetzt welche Variable steht.
Dateien, die man öffnet, muß man auch wieder schließen, indem man sie in einem with-Statement öffnet.
Du bekommst mit `walk` schon `files`. Warum dann nochmal ein os.listdir?
Und warum bist Du jetzt auf die os-Funktionen wieder zurückgefallen, und benutzt nicht mehr pathlib?
Denn Pfade sind keine Strings, Du gehst aber mit `split` drauf los.
Oben hast Du was von Nummern und Text-Dateien geschrieben, was jetzt hier im Code gar nicht mehr auftaucht. Ist das nicht relevant?
Und gibt es noch im Unterordner weitere Unterordner? Was soll passieren, wenn sich die Namen der Unterunterordner wiederholen?

Aus Deiner Beschreibung und aus dem Code würde ich jetzt raten, dass Du eigentlich das möchtest:

Code: Alles auswählen

from pathlib import Path

OUTPUT_PATH = Path("/home/ja/meinordner/mein_backup")
INPUT_PATH = Path("/home/ja/meinordner/samonestozatest")

def main():
    for path in INPUT_PATH.iterdir():
        if path.is_dir():
            textfiles = [f.name for f in path.glob("*.txt") if f.name != "list.txt"]
            output_filename = (OUTPUT_PATH / path.name).with_suffix('.txt')
            output_filename.write_text(",".join(textfiles))

if __name__ == "__main__":
    main()
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Danke @__Sirius__,
ist viel einfacher dein bsp, ich werde es morgen mal testen.
Warum wieder auf os, weil ich das hier " [f.name for f in path.glob("*.txt") if f.name != "list.txt"] "nicht geschafft habe.
Ja das mit den Nummern und txt, in diesen Unterordner kann es nichts anderes geben als txt, eigentlich tatsächlich wenn ich es jetzt sehe, es ist nicht wichtig explicit nach txt zu suchen, es sind nur txt. Es kann sein das weitere Unterordner vorkommen, aber die Namen und die Unterordner wiederholen sich nicht. Ich berichte morgen.

Vielen Vielen Dank für dein bsp
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo @Sirius3,
Danke für dein bsp, es geht musste etwas ändern und jetzt geht es.
"Deine Frage:
Und gibt es noch im Unterordner weitere Unterordner?"
Genau heute habe ich diesen Fall das im Unterordner Unterordner vorhanden sind, habe versucht mit * beim Path("/home/ja/meinordner/samonestozatest/*")
leider klappt das nicht auch nicht mit **/*.txt, was muss da jetzt hin damit es wieder geht?
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du Unterverzeichnisse hast, dann mußt Du rekursiv alle Verzeichnisse durchgeben.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Ich habe jetzt im path.glob("**/*.txt"), aber leider passt es noch nicht. Es werden die txt Dateien im Unterordner vom Unterordner gefunden, aber Ich habe jetzt keine Unterordner.txt mit den Dateien aus 2 Unterordner, sonder die Dateien aus Unterordner 2, stehen in der text Datei Unterordner 1.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo,

versuche gerade nochmal hier mit dem bsp von Sirius3 Unterverzeichnis vom Unterverzeichnis durchzugehen.
Leider bekomme ich den Inhalt nicht so wie ich es mir vorstelle. Ich dachte ich suche hier schon rekursiv, habe Unterordner im Unterordner1 es wird der Inhalt in einer txt erzeugt aber mit dem Namen des ersten Unterordner und nicht Unterordner1.
bsp:
Unterordner 1.txt, 2.txt, 3.txt -> Unterordner.txt Inhalt 1.txt, 2txt, 3.txt das passt, so hätte ich es gerne für jeden Unterordner vom Unterordner,
aber bei
Unterordner Unterordner1 1.txt,2.txt Unterordner2 11.txt, 22.txt bekomme ich Unterordner.txt Inhalt 1.txt, 2.txt, 11.txt, 22.txt
wünsche mir aber Unterordner1.txt Inhalt 1.txt, 2txt, Unterordner2.txt Inhalt 11.txt, 22.txt, der erste Unterordner soll ignoriert werden.


Eigentlich ist das bsp von Sirius3 perfekt wenn ich im Verzeichnis gleich Unterordner mit Inhalt habe aber wenn ich Unterordner und dann nochmal Unterordner und nochmal Unterordner mit Dateien habe, da passt es leider nicht mehr, es wird eine txt Datei erstellt aber zugeordnet zum erstem Unterordner.
Was muss man in dem bsp anpassen damit es funktioniert.

Code: Alles auswählen

from pathlib import Path

OUTPUT_PATH = Path("/home/ja/meinordner/mein_backup")
INPUT_PATH = Path("/home/ja/meinordner/samonestozatest")

def main():
    for path in INPUT_PATH.iterdir():
        if path.is_dir():
            textfiles = [f.name for f in path.glob("**/*.txt") if f.name != "list.txt"]
            output_filename = (OUTPUT_PATH / path.name).with_suffix('.txt')
            output_filename.write_text(",".join(textfiles))

if __name__ == "__main__":
    main()
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Du willst also für jeden Unterunterordner eine eigene Datei mit den Text-Dateien nur in diesem Verzeichnis, ohne die Unterordner zu berücksichtigen.
Dann mußt Du in der äußeren Schleife alle Ordner durchlaufen und in der Liste-Comprehension nur die .txt-Datein im aktuellen Verzeichnis auflisten.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Danke Sirius3,
ich schaffe es nicht leider, wenn ich das ändere for path in INPUT_PATH.iterdir(): in for path in glob.glob(path, recursive=True) dann kann ich mit print alles ausgeben, aber dann ist auch ende. Schade
Vielen Dank
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Bitte nicht beschrieben, was Du an Code geändert hast, sondern einfach den geänderten Code posten, und dann die Fehlermeldung posten, oder wie das Ergebnis von der Erwartung abweicht.

Wieso glob.glob? INPUT_PATH.rglob('*') wäre das richtige.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Vielen Dank Sirius3,
vielleicht erkläre ich es nicht richtig aber danke dir vielmals das du versuchst mir zu helfen.

Habe jetzt folgendes geändert INPUT_PATH.glob('**/') da bekomme ich dann alle Ordner und Unterordner zu sehen, ich denke so sollte es klappen, mit * bekomme ich leider nicht die Subfolder vom Subfolder zu sehen.
Liste-Comprehension nur die .txt-Datein im aktuellen Verzeichnis auflisten -> da bin ich dran jetzt, das muss ich noch hin bekommen.

Ich versuche nochmal die Struktur zu beschreiben. Die .txt sind alle unterschiedlich nur hier zum verständnis.

samonestozatest/ganjatestsubfolder/1.txt,2.txt
samonestozatest/ganjatestsubfolder1/ganjatestsubfolder11/1.txt,2.txt
samonestozatest/ganjatestsubfolder2/ganjatestsubfolder22/1.txt,2.txt,3.txt
samonestozatest/ganjasubfolder3/1.txt,2txt

print (path.name) gibt aktuell folgendes aus, nur Ordner
ganjatestsubfolder
ganjatestsubfolder1
ganjatestsubfolder11
ganjatestsubfolder2
ganjatestsubfolder22
ganjatestsubfolder3

Code: Alles auswählen

from pathlib import Path

OUTPUT_PATH = Path("/home/ja/meinordner/mein_backup")
INPUT_PATH = Path("/home/ja/meinordner/samonestozatest")

def main():
    for path in INPUT_PATH.glob('**/'):
        if path.is_dir():
            print (path.name)
            #textfiles = [f.name for f in path.glob("**/*.txt") if f.name != "list.txt"]
            #output_filename = (OUTPUT_PATH / path.name).with_suffix('.txt')
            #output_filename.write_text(",".join(textfiles))

if __name__ == "__main__":
    main()
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du hast an anderer Stelle hier doch schon rglob benutzt. Fuer "recursive glob". Warum verschwindet das ploetzlich wieder?
Antworten