Seite 2 von 2

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Samstag 26. Mai 2012, 18:26
von Hyperion
Auch wenn Du nun meine Nachfrage erneut ignoriert hast, schrieb ich Dir doch schon die Lösung. `os.rename` ist Dein Freund.

Da es *immer* exakt sechs Zeichen sind, hast Du die Lösung schon im Link von /me erhalten... aber ich spiele mal Vorleser:

Code: Alles auswählen

In [2]: os.path.splitext("Name_i=5_12345.txt")
Out[2]: ('Name_i=5_12345', '.txt')

In [3]: filename, ext = os.path.splitext("Name_i=5_12345.txt")

In [4]: filename[:-6]
Out[4]: 'Name_i=5'

In [5]: "%s%s" % (filename[:-6], ext)
Out[5]: 'Name_i=5.txt'
Dazu braucht es - neben dem Wissen um `os.path.splitext`, was Dir BlackJack ja nannte - nur "Slicing". Und das ist absolutes Grundlagenwissen!

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Sonntag 27. Mai 2012, 11:04
von 01detlef
Hallo,

vielen Dank für die Hilfe. Sollte man die beiden Teile (filename[:,-6] und ext) mit join wieder verbinden, das habe ich irgendwo mal gelesen?

Wenn ich den neuen Namen dann zusammengesetzt habe, muss man dann nochmal extra sagen, dass die Datei gespeichert wird unter dem neuen Namen?

Code: Alles auswählen

os.renames(old,new)

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Sonntag 27. Mai 2012, 11:26
von 01detlef
Hallo,

also ich dachte da nun an sowas:

Code: Alles auswählen

for file in glob.glob('Name*'):
       filename,ext = os.path.splitext(file)
       newfilename = ''.join([filename,ext])
       os.renames(filename,newfilename)
Macht das soweit Sinn?

detlef

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Sonntag 27. Mai 2012, 12:04
von BlackJack
@01detlef: Mal abgesehen davon, dass ich statt `join()` hier den ``+``-Oerator verwenden würde, überlege doch mal selbst ob das Sinn macht. Mal angenommen es wären keine Fehler drin, würdest Du den Namen zerlegen und wieder zusammen setzen und dann von welchem Namen zu welchem Namen umbenennen‽

Gehe in Gedanken durch was jede Anweisung zur Laufzeit macht, spiele also selbst Python-Interpreter. Stell Dir selbst die Frage „Welcher Wert ist wann an welchen Namen gebunden?” und beantworte sie Dir. Dann vergleichst Du Deine Erwartungen mit der Realität. Zum Beispiel in dem Du ein paar ``print``-Anweisungen einstreust um die Werte zu überprüfen. Probiere an einem Verzeichnis mit Testdateien mit entsprechenden Namen.

Der Name `file` ist irreführend, weil `glob()` keine Datei-Objekte, sondern Zeichenketten liefert, die Pfad- bzw. Dateinamen enthalten.

Vielleicht solltest Du auch nicht so viel Quelltext schreiben ohne ihn auszuprobieren. Und ja, vier Zeilen können für einen Anfänger schon viel sein. Entwickle den Code nicht, in dem Du viel schreibst und dann hier nachfragst, sondern in dem Du das selber Stück für Stück entwickelst, und jeden Schritt testest und erst weiteren, neuen Quelltext dazu schreibst, wenn der bisherige das (Teil)Ergebnis liefert, welches Du haben wolltest.

Das fängt an mit einem Grundgerüst:

Code: Alles auswählen

#!/usr/bin/env python
from glob import glob


def main():
    for path in glob('Name*'):
        print path


if __name__ == '__main__':
    main()
Laufen lassen und schauen ob das bis dahin das tut was es soll:

Code: Alles auswählen

bj@s8n:~/tmp$ ls Name*
Name_i=10_18372.txt  Name_i=15_76382.txt  Name_i=5_12345.txt
bj@s8n:~/tmp$ ./test.py
Name_i=5_12345.txt
Name_i=15_76382.txt
Name_i=10_18372.txt
Nächster Schritt ist das zerlegen des Dateinamens in Name und Erweiterung:

Code: Alles auswählen

    for path in glob('Name*'):
        old_filename, extension = os.path.splitext(path)
        print old_filename, '|', extension
Testlauf:

Code: Alles auswählen

bj@s8n:~/tmp$ ./test.py
Name_i=5_12345 | .txt
Name_i=15_76382 | .txt
Name_i=10_18372 | .txt
Dann setzt Du beides wieder zusammen:

Code: Alles auswählen

    for path in glob('Name*'):
        old_filename, extension = os.path.splitext(path)
        new_filename = old_filename + extension
        print old_filename, '->', new_filename
Testlauf:

Code: Alles auswählen

bj@s8n:~/tmp$ ./test.py
Name_i=5_12345 -> Name_i=5_12345.txt
Name_i=15_76382 -> Name_i=15_76382.txt
Name_i=10_18372 -> Name_i=10_18372.txt
An der Stelle kann man vielleicht auch schon erahnen was die Sinnhaftigkeit eines Umbenennens von `old_filename` nach `new_filename` angeht. Dann sollte man hier nicht mit `os.rename()` weiter machen, sondern erst einmal dafür sorgen, dass die Daten bis zu diesem Punkt im Programmablauf sinnvolle Werte annehmen.

Falls das Problem nicht offensichtlich war, wird es spätestens beim Versuch umzubenennen klar:

Code: Alles auswählen

    for path in glob('Name*'):
        old_filename, extension = os.path.splitext(path)
        new_filename = old_filename + extension
        print old_filename, '->', new_filename
        os.rename(old_filename, new_filename)
Testlauf:

Code: Alles auswählen

bj@s8n:~/tmp$ ./test.py
Name_i=5_12345 -> Name_i=5_12345.txt
Traceback (most recent call last):
  File "./test.py", line 15, in <module>
    main()
  File "./test.py", line 11, in main
    os.rename(old_filename, new_filename)
OSError: [Errno 2] No such file or directory
Wenn man länger programmiert und die Erfahrung wächst, werden die Quelltextabschnitte grösser, die man zwischen Testläufen schreiben kann, ohne dass man zu viele Fehler in den Abschnitt einbaut. Aber für den Anfang kann es Sinn machen jede Zeile zu prüfen ob sie den Erwartungen entspricht, bei komplexeren Sachen sogar für Teilausdrücke innerhalb einer Zeile.

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Sonntag 27. Mai 2012, 12:07
von Hyperion
Du solltest Code mal in einer Shell ausprobieren! So macht das doch gar keinen Sinn. `filename` ist bei Dir ja gar nicht der *alte* Dateiname, sondern ein "verstümmelter" Teil davon!

Im übrigen solltest Du im Kopf der `for`-Schleife nicht den Namen `file` benutzen. Das ist ja gar kein File-Objekt, sondern ein Dateiname. Also benutze doch an dieser Stelle den Namen `filename`. Weiter unten nennst Du das dann eben `root`, wie es in der Doku (`os.path.splitext`) vorgeschlagen wird.

Bei Python 2.x solltest Du `file` generell nicht benutzen, da Du damit eine Built-in Funktion überschreibst.

`str.join()` benutzt man immer dann, wenn man ein `Iterable` mit String-Objekten hat, typischer Weise oftmals eine Liste. Wenn man diese aber erst künstlich generiert, wie Du es tust, dann ist das der falsche Weg. Ich habe Dir ja eine Möglichkeit bereits angegeben, Du kannst auch die `str.format()`-Methode nutzen.

Ach ja, meine Frage hast Du schon wieder nicht beantwortet :-D

PS: BlackJack war schneller, ich lasse das dennoch mal so stehen, insbesondere, weil die Frage ja noch im Raum steht... ;-)

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Sonntag 27. Mai 2012, 12:23
von 01detlef
@Hyperion: Meinst du die Frage, um was für ein Programm es sich handelt? Es soll ein alias-Befehl aufgerufen werden, also nicht mv oder cp.

@Blackjack: Vielen Dank. Ich wollte rename-Aufruf verwenden, weil ich nicht so ganz verstehe, warum der Dateiname sofort geändert wird, ohne nochmal direkt zu sagen, dass er "gespeichert" werden soll.

Vielen Dank für eure Hilfe.

detlef

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Sonntag 27. Mai 2012, 12:28
von Hyperion
01detlef hat geschrieben:@Hyperion: Meinst du die Frage, um was für ein Programm es sich handelt? Es soll ein alias-Befehl aufgerufen werden, also nicht mv oder cp.
Ok. Oftmals wollen User hier Dinge per Shell lösen, für die Python direkt Funktionalität anbietet. Also etwas die grundlegende Dinge wie Kopieren, Verschieben, usw., aber auch Dinge wie `tar`, `zip`, das Erstellen von Prüfsummen uvm. So etwas löst man dann eben besser nicht über den Umweg `subprocess`. Daher fragte ich nach :-)

Dein "Alias" kann natürlich immer noch Dinge beinhalten, auf die das zutrifft ;-)

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Sonntag 27. Mai 2012, 15:01
von BlackJack
@01detlef: Bei „gefährlichen” Sachen sollte man auch immer überlegen was zum Beispiel passiert wenn es mehrfach aufgerufen wird, oder wenn schon Zieldateien mit gleichen Namen existieren.

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Montag 28. Mai 2012, 09:05
von 01detlef
Vielen Dank für eure Hilfe. Ich muss nochmal nachfragen, weil ich das immer noch nicht verstehe, wieso das so funktioniert.
new_filename = old_filename + extension
print old_filename, '->', new_filename
Ich habe mir dann die neuen Namen zusammengesetzt, aber wieso weiss er dann automatisch, dass die auch so direkt umbenannt wird. Also ich habe den neuen String, aber wieso wird die Datei dann auch direkt umbenannt?

detlef

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Montag 28. Mai 2012, 09:21
von BlackJack
@01detlef: Da wird doch keine Datei umbenannt‽ Das macht `os.rename()`.

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Montag 28. Mai 2012, 09:51
von 01detlef
Hallo,

aber dann verstehe ich den Beitrag von BlackJack nicht. Er schreibt ja, dass bei rename eine Fehlermeldung auftritt. Es ist also richtig, dass der neue Name noch nicht der Datei zugeordnet ist? Also muss ich doch noch ein rename machen?!

detlef

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Montag 28. Mai 2012, 12:44
von Hyperion
Ich verstehe nun wiederum Deinen Beitrag nicht und bin verwirrt!

`os.rename` benennt eine Datei um. Fertig. Natürlich tut es das nicht, wenn ein Fehler auftritt. Lies Dir dazu noch mal dieses Posting von mir durch, insbesondere den ersten Absatz! BlackJack hatte den Fehler in seinem ausführlichem Posting darüber *extra* so gelassen, damit Du selber darauf kommst. (Nehme ich mal an)

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Montag 28. Mai 2012, 16:06
von 01detlef
Hallo,

also ich hatte das so verstanden, dass ich mit

Code: Alles auswählen

    for path in glob('Name*'):
        old_filename, extension = os.path.splitext(path)
        new_filename = old_filename + extension
        print old_filename, '->', new_filename
den neuen Namen definieren kann und ebenfalls der neue Dateiname schon abgespeichert ist?! Weil mit dem os.rename tritt ja ein Fehler auf???

detlef

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Montag 28. Mai 2012, 16:29
von Hyperion
01detlef hat geschrieben: also ich hatte das so verstanden, dass ich mit

Code: Alles auswählen

for path in glob('Name*'):
    # hier bekommst Du zwei Strings
    old_filename, extension = os.path.splitext(Pathos)
    # hier baust Du einen neuen String zusammen
    new_filename = old_filename + extension
    # hier gibst Du den String aus
    print old_filename, '->', new_filename
den neuen Namen definieren kann und ebenfalls der neue Dateiname schon abgespeichert ist?!
Hä? Wie sollte das gehen!?! s. meine Kommentare im Code! An welcher Stelle sollte so etwas passieren? Python und Programmiersprachen i.A. sind doch nichts "magisches" und verfügen über hellseherische Fähigkeiten von dem, was Du erreichen willst! Du schreibst *nirgends* irgend etwas in Deinen Code, welches eine Datei auf Deiner Festplatte umbenennt! Wie ich Dir ja schon unlängst schrieb, benutzt man dafür `os.rename`.
01detlef hat geschrieben: Weil mit dem os.rename tritt ja ein Fehler auf???
Ja und was sagt uns das? Denk mal drüber nach und *lies* Dir die von mir bereits genannte Stelle noch mal durch. Sollte das immer noch nicht klar sein, dann schau Dir die Ausgabe mal *exakt* an! Dann solltest Du darauf kommen, wieso dieser Fehler auftritt. Und wenn das nicht hilft, dann überprüfe eben mal in einer Shell, ob Du die Datei, die Du in `old_filename` vermutest, auf Deiner Platte findest.

Als letzten Tipp: Dein OS kann ja nur Dinge umbenennen, die auch existieren ;-)

Und als letzten Hinweis: Bitte benutze für Python-Code die Python-Code-Tags: [ code=python ] [ /code ] (ohne die Leerzeichen)

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Montag 28. Mai 2012, 18:42
von 01detlef
Hallo,

meinst du, weil die Namen new und old genau identisch sind? Also dann würde ich das so ändern:

Code: Alles auswählen

    for path in glob('Name*'):
        old_filename, extension = os.path.splitext(path)
        new_filename = old_filename[:-6] + extension
        print old_filename, '->', new_filename
        os.rename(old_filename, new_filename)
Meckert rename also, wenn die beiden Dateinamen identisch sind? Ich dachte, das wird missachtet.

detlef

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Montag 28. Mai 2012, 18:49
von Hyperion
*seufz* `old_filename` ist *nicht* der "alte" Dateiname, sondern nur ein *Teil* davon! In `path` befindet sich der "alte" Dateiname - war das so schwer?

Ich habe diesen Namen ja auch genau deswegen kritisiert (s. mein verlinktes Posting, erster Absatz)... dass Du selber auf Deinen falschen Namen reingefallen bist, macht Dir hoffentlich deutlich, dass man Namen immer sinnvoll benennen sollte und dass die Namenswahl allgemein sehr *wichtig* ist :-)

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Montag 28. Mai 2012, 18:52
von 01detlef
ah ok,
jetzt sehe ich das Problem. Oh man, stimmt natürlich!

vielen dank,
detlef

Re: Alle Dateien mit gleichem Dateinamenanfang öffnen

Verfasst: Dienstag 29. Mai 2012, 04:48
von Leonidas
Hyperion hat geschrieben:Ich habe diesen Namen ja auch genau deswegen kritisiert (s. mein verlinktes Posting, erster Absatz)... dass Du selber auf Deinen falschen Namen reingefallen bist, macht Dir hoffentlich deutlich, dass man Namen immer sinnvoll benennen sollte und dass die Namenswahl allgemein sehr *wichtig* ist :-)
Phil Karlton hat geschrieben:There are only two hard things in Computer Science: cache invalidation and naming things