Wildcard

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
freund
User
Beiträge: 9
Registriert: Sonntag 16. August 2015, 15:11

Hallo Freunde,

ich habe folgenden Code:

Code: Alles auswählen

import os
import datetime
path="/home/pi/"
dt = str(datetime.datetime.now())
newname = 'image01'+dt+'.jpg'
os.rename(path + 'image01.jpg', newname)
Das funktioniert wunderbar.
Ich benötige aber noch eine Wildcard, so das der Code auf alle .jpg Bilder mit der Umbenennung greift (praktisch muss es unabhängig von dem sein, was vor dem .jpg steht).
Leider habe ich davon keine Ahnung.

Kann mir das eventuell einer mit implementieren?

Grüße
freund
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@freund: mit os.listdir() erhältst Du den Inhalt eines Verzeichnisses. Darüber kannst Du dann interieren.
BlackJack

@freund: Schau Dir mal das `glob`-Modul an.
freund
User
Beiträge: 9
Registriert: Sonntag 16. August 2015, 15:11

Danke für eure Antworten.
Ich habe es jetzt so versucht. Die Konsole bringt mir aber den Fehler:
os.rename(path + '.jpg', newname)
TypeError: can only concatenate list (not "str") to list

Code: Alles auswählen

import os
import datetime
import glob

path=glob.glob('./*.jpg')
dt = str(datetime.datetime.now())
newname = dt+'.jpg'
os.rename(path + '.jpg', newname)
Anscheinend hat er ja erkannt das es sich um eine Liste handelt (concatenate=Verkettung) statt um eine einzelne Datei.

Was mache ich falsch?
BlackJack

@freund: Anscheinend hast Du ja auch erkannt das es sich bei `path` um eine Liste handelt. Was denkst Du denn was da drin ist und was es bringen soll an eine Liste eine Zeichenkette zu addieren?

Schau Dir doch einfach mal an was `path` enthält.
freund
User
Beiträge: 9
Registriert: Sonntag 16. August 2015, 15:11

Stimmt!

Code: Alles auswählen

import datetime
import os
import glob

dt = str(datetime.datetime.now)

for filename in glob.glob('*.txt'):
    os.rename(filename, dt + '.txt')
Läuft ohne Fehler durch.
Wenn ich mir die Liste der Dateien anzeigen lasse sehe ich die Dateinamen jetzt mit:
<built-in method now of type object at 0x964800>.txt

Was kann das sein?

Danke für eure Hinweise


Edit:
() nach now hat gefehlt.


Problem jetzt: alle Dateien werden mir überschrieben wie es aussieht.
Mit:

Code: Alles auswählen

time.sleep()
Dachte ich kann ich ein kleines Zeitfenster einstellen. Aber anscheinend ohne Erfolg.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Bei `now` sind dir Klammern abhanden gegangen.

Die `datetime.datetime` Objekte haben uebrigens noch eine `strftime` Methode mit der du einfach die Zeit formatieren kannst, inklusive der Dateiendung und eventueller Praefixe.
BlackJack

@freund: Du erzeugst *einmal* eine Zeichenkette mit der aktuellen Zeit und erwartest dann das das die sich auf magische Weise aktualisiert wenn Du sie irgendwo benutzt‽
freund
User
Beiträge: 9
Registriert: Sonntag 16. August 2015, 15:11

@ BlackJack:
ich könnte eher eine Hilfreiche Antwort wie von cofi gebrauchen.
Aber um dich zu bestätigen: ja, erwarte ich.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Das von BlackJack war eine hilfreiche Antwort.
Du erzeugst aus einer Zeit eine Zeichenkette. Wenn ich jetzt auf einen Zettel 16:55 schreibe, dann wird dort an der Stelle auch in 10 Minuten noch 16:55 stehen und nicht 17:05.
freund
User
Beiträge: 9
Registriert: Sonntag 16. August 2015, 15:11

Stimmt. Bitte entschuldige meine Ausdrucksweise.

D.h. also das ich mit "os.listdir()" mir erst eine Liste ausgeben muss?
BlackJack

@freund: Nun das ist dann eine falsche Erwartung. Eine Zeichenkette ist eine Folge von Zeichen. Die hat keine Ahnung wie sie mal zustande gekommen ist und ändert sich nicht auf magische Weise so wie man sich das wünscht. Programmiersprachen machen das was man sagt, nicht das was man meint. ;-)
freund
User
Beiträge: 9
Registriert: Sonntag 16. August 2015, 15:11

Ich dachte aber die Zeichenkette wird auf alle .txt - Dateien angewendet; mit glob dachte ich, bekomme ich schon eine Liste ausgegeben.
BlackJack

@freund: Ähm, ja die *eine* sich *nicht ändernde* Zeichenkette wird als Grundlage für alle Quelldateien genommen, das heisst alle Quelldateien werden zu diesem einen Dateinamen umbenannt, was halt dazu führt das am Ende nur noch ein Dateiname existiert und darüber die letzte umbenannte Datei erreichbar ist. ``dt + '.txt'`` ergibt immer die gleiche Zeichenkette denn der Wert von `dt` ändert sich nicht auf magische Weise.
freund
User
Beiträge: 9
Registriert: Sonntag 16. August 2015, 15:11

Wie kann ich denn dann verschiedene Zeichenketten erstellen (z.B. mit Zeit + 1) ?
BlackJack

@freund: Was meinst Du mit Zeit + 1? Was ist denn das *eigentliche* Ziel von dieser Aktion? Macht das denn überhaupt Sinn den Dateien auf diese Weite einen zeitbasierten Namen zu geben? Ist Dir klar das die Reihenfolge der Namen wie sie von `glob` geliefert werden nahezu beliebig sein kann‽

Edit: Im ersten Beitrag sieht es noch so aus als sollte der alte Dateiname erhalten bleiben und nur die aktuelle Zeit eingefügt werden. *Dann* käme man ja auch prima mit *einer* Zeitangabe für alle Dateinamen aus.

Edit2: In dem Fall hilft `os.path.splitext()` sehr wahrscheinlich weiter. Und bitte Zeichenkettenformatierung mit der `format()`-Methode statt `str()` und ``+``. Letzteres ist eher BASIC als Python.

Edit3: Und `os.path.join()` statt ``+`` für Pfadteile.
BlackJack

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
import os
from datetime import datetime as DateTime
from glob import iglob


def main():
    path = '/home/pi'
    now = DateTime.now()
    for filename in iglob(os.path.join(path, '*.jpg')):
        name, extension = os.path.splitext(filename)
        os.rename(
            filename, '{0}_{1:%Y-%m-%d_%H%M%S}{2}'.format(name, now, extension)
        )


if __name__ == '__main__':
    main()
Wenn man so etwas entwickelt, gerade wenn man die Sprache und die Datentypen und Operationen noch nicht so gut, ist es immer hilfreich wenn man damit ein wenig in einer Python-Shell herumexperimentiert um zu sehen wie die Zwischenergebnisse aussehen.

Code: Alles auswählen

In [11]: from datetime import datetime as DateTime

In [12]: import os

In [13]: filename = 'some/path/image.jpg'

In [14]: name, extension = os.path.splitext(filename)

In [15]: name
Out[15]: 'some/path/image'

In [16]: extension
Out[16]: '.jpg'

In [17]: now = DateTime.now()

In [18]: '{0}_{1:%Y-%m-%d_%H%M%S}{2}'.format(name, now, extension)
Out[18]: 'some/path/image_2015-08-27_094727.jpg'
Antworten