Push-Nachrichten von MacTechNews.de
Würden Sie gerne aktuelle Nachrichten aus der Apple-Welt direkt über Push-Nachrichten erhalten?
Forum>Software>Sehr viele Dateien aus Unterordnern in gemeinsamen übergeordneten Ordner legen - wie automatisieren?

Sehr viele Dateien aus Unterordnern in gemeinsamen übergeordneten Ordner legen - wie automatisieren?

Kehrblech07.06.2515:30
Hallo,
ich habe ca. 150.000 Fotos plus zugehörige Bearbeitungsdateien (xml u.ä.) in Jahres-, Monats- und Tagesordnern. Leider hat sich jedoch im Verlauf der Jahre eingeschlichen, dass es zu vielen Tagesordnern noch stündliche und minütliche, teilweise noch sekündliche Unterordner (oft nur mit einem einzigen Bild/Datei)gibt, was die Übersicht sehr erschwert.
Gibt es einen "Befehl" / eine Routine / ein Programm, dass die Dateien (sie liegen auf einem Synology-NAS) durchgeht und sämtliche Dateien auf die Ebene der "Tagesordner" hebt und, nach Möglichkeit, die dann leeren Unterordner löscht?
Vor einiger Zeit habe ich mich selbst schon einmal mit Automator daran versucht, hatte aber keinen wirklichen Erfolg (wahrscheinlich aus Mangel an Erfahrung mit Automator). Händisch habe ich zwar schon mal angefangen, aber die Bereinigung dauert ewig – und schreit geradezu nach Automatisierung. Wie gesagt: die Dateien liegen auf meinem Synology NAS (DS923+), können also entweder per Mac-Finder oder per Synology File Station bewegt werden.
Falls mir jemand helfen könnte, wäre ich ihm/ihr sehr verbunden!

Danke!
0

Kommentare

sudoRinger
sudoRinger07.06.2515:45
Kürzlich habe ich ein Skript erstellt, das leere Unterordner gesucht hat, um diese zu löschen. Das könnte ich ggf. anpassen. Welches Format haben die Namen der zu löschenden Unterordner?

MIt etwas manueller Arbeit geht die Aufgabe mit Devonthink. Du indexierst das Verzeichnis mit den 150.000 Fotos. In Devonthink nennen sich die Ordner dann Gruppen. Wenn eine Gruppierung aufgehoben wird, dann ist der Inhalt in der übergeordneten Gruppe (= Ordner auf der Synology).
Nun erstellt du einen intelligenten Ordner, der alle zu löschenden Gruppen anhand des Namensmusters filtert. Diese Gruppen markierst Du und hebst die Gruppierung auf. Die Dateien landen automatisch in der übergeordneten Gruppe, was sich direkt auf die Ordnerstruktur der Synology auswirkt.
+2
Kehrblech07.06.2516:23
Danke, sudoRinger!
Da ich Devonthink nicht benutze, wäre mir ein Skript natürlich lieber.
Die Namen der Unterordner haben das Format: JJJMMDD-[sechstellige Zahl], z.B. "20080509-130138". Das Format ist aber im Grunde nicht so wichtig, da es keine anderen Unterordner gibt. Hat man also alle Dateien auf die Tagesebene in der Ordnerstruktur aus Jahr – Monat – Tag – "weitere Unterordner" gebracht, können sämtliche, dann leere Unterordner der einzelnen Tage gelöscht werden.
Wenn Du mir mit Deinem Skript helfen würdest, wäre das fantastisch!

In jedem Fall schon einmal herzlichen Dank!
0
sudoRinger
sudoRinger07.06.2517:44
ist das die Struktur?
2018/
└── 12/
    └── 06/
       ├── foto1.jpg
       ├── foto2.xml
       ├── 20181206-130138/
              └── foto3.jpg

Gibt es Fotos mit identischem Namen in unterschiedlichen Unterordnern? Benötigt das Skript einen Überschreibschutz?
+1
Kehrblech07.06.2519:38
sudoRinger
ist das die Struktur?
2018/
└── 12/
    └── 06/
       ├── foto1.jpg
       ├── foto2.xml
       ├── 20181206-130138/
              └── foto3.jpg

Gibt es Fotos mit identischem Namen in unterschiedlichen Unterordnern? Benötigt das Skript einen Überschreibschutz?
Ja, die Struktur ist korrekt.
Gelegentlich gibt es ein Foto (z.B. "foto1.jpg"), das sowohl im Ordner 06/ als auch identisch im Ordner 20181206-130138 existiert. Dieses Foto benötige ich natürlich nur einmal. Es könnte also z.B. mit dem Ordner 20181206-130138 gelöscht werden, könnte aber auch erst auf die Ordnerebene 06/ gelegt werden und dabei die bereits vorhandene Kopie überschreiben. Wichtig ist nur, dass mindestens eine Version erhalten bleibt.
Wenn ich händisch arbeite, markiere ich sämtliche Dateien im Unterordner 201812… und verschiebe sie auf die 06/-Ordnerebene. Kommt es zu Nachfragen, wie mit der doppelten Datei umgegangen werden soll, klicke ich auf "Überschreiben".
Ich hoffe, das hilft!
Und nochmals herzlichen Dank für Deine Mühe!
+1
sudoRinger
sudoRinger07.06.2520:28
So könnte es funktionieren

#!/bin/bash

base_path="$1"

# Tagesordner auf 3. Ebene finden
find "$base_path" -type d -mindepth 3 -maxdepth 3 | while read day_folder; do
    echo "Bearbeite: $day_folder"
    
    # Jeden Unterordner im Tagesordner finden
    find "$day_folder" -type d -maxdepth 1 -name "*-*" | while read subfolder; do
        subfolder_name=$(basename "$subfolder")
        
        # Dateien in übergeordneten Tagesordner verschieben und Ordner löschen
        find "$subfolder" -type f -exec mv {} "$day_folder/" \;
        rmdir "$subfolder" 2>/dev/null
    done
done

echo "Fertig!"

Wenn das Skript als flatten.sh gespeichert wird, machst Du es mit chmod +x flatten.sh ausführbar.
Gestartet wird es mit flatten.sh /pfad/zu/Fotos.

Das Skript hat keine Fehlerbehandlung und überschreibt gnadenlos gleichnamige Files. Am besten prüfst du mit dupeGuru vorher, ob du Duplikate hast. Ein Backup ist sicherlich auch sinnvoll ...

Das -name "*-*" kann entfernt werden, wenn jeder Unterordner unabhängig vom Format JJJMMDD-[sechstellige Zahl] aufgelöst werden soll.
+4
Kehrblech07.06.2523:37
Danke, sudoRinger! Großartig!
Morgen werde ich mich mal ans Ausprobieren machen.
Ich melde mich.
0
AidanTale08.06.2506:41
sudoRinger
Wenn das Skript als flatten.sh gespeichert wird, machst Du es mit chmod +x flatten.sh ausführbar.
Gestartet wird es mit flatten.sh /pfad/zu/Fotos.

Wenn du dich im Terminal im Ordner befindest wo das Skript liegt, musst du es mit:
./flatten.sh /pfad/zu/Fotos
starten, sonst wird es nicht gefunden. Alternativ kann man auch den kompletten Pfad zum Skript angeben, also z.B.:
/Users/dummy/flatten.sh /pfad/zu/Fotos
Ich sehe zwar keine offensichtlichen Probleme, aber bevor das Skript Files verschiebt und Ordner löscht könnte man einen Testlauf durchführen und die entsprechenden Kommandos nur ausgeben lassen. Dazu kann man einfach echo in diese beiden Zeilen im Skript einfügen und es dann ausführen:
    find "$subfolder" -type f -exec echo mv {} "$day_folder/" \;
    echo rmdir "$subfolder" 2>/dev/null
+2
Kehrblech08.06.2515:50
Nochmals vielen Dank für Eure Mühe.
Leider komme ich nicht recht weiter.
Wenn ich das Skript als flatten.sh in meinem User-Verzeichnis abspeichere, dann über "chmod +x flatten.sh" ausführbar mache und anschließend den Pfad eines Testordners als "/Volumes/home/Routinentest/2" auf dem NAS anhänge (in dem sich die Testfotos gemäß der Struktur "Jahr/Monat/Tag/foto-n.dng," befinden), passiert das folgende:
MacBook-Pro-M1 ~ % ./flatten.sh /Volumes/home/Routinentest/2
./flatten.sh: line 6: find /Volumes/home/Routinentest/2 -type d -mindepth 3 -maxdepth 3 : No such file or directory
./flatten.sh: line 6:  while read day_folder: command not found
./flatten.sh: line 6:  do: command not found
./flatten.sh: line 7:     echo Bearbeite: : command not found
./flatten.sh: line 8:     : command not found
./flatten.sh: line 9:     # Jeden Unterordner im Tagesordner finden: command not found
./flatten.sh: line 10:     find  -type d -maxdepth 1 -name *-* : command not found
./flatten.sh: line 10:  while read subfolder: command not found
./flatten.sh: line 10:  do: command not found
./flatten.sh: line 11: basename : command not found
./flatten.sh: line 11:         subfolder_name=: command not found
./flatten.sh: line 12:         : command not found
./flatten.sh: line 13:         # Dateien in übergeordneten Tagesordner verschieben und Ordner löschen: command not found
./flatten.sh: line 14:         find  -type f -exec echo mv {} / ;: No such file or directory
./flatten.sh: line 15:     echo rmdir  2: command not found
./flatten.sh: line 16:     done: command not found
./flatten.sh: line 17: syntax error near unexpected token `done'
./flatten.sh: line 17: `done'
"flatten.sh" scheint also das Verzeichnis mit dem Testordner "2" gar nicht zu finden. Immerhin aber wird flatten.sh gefunden, da sonst ja gar nichts passieren würde. Ist die Pfadangabe falsch? Diese habe ich per <alt> + klick aus dem Finder kopiert.

Ich vermute, ich mache irgendeinen Anfängerfehler, da ich zum ersten Mal mit einem Skript im Terminal arbeite.
Könnt Ihr mir helfen?
0
sudoRinger
sudoRinger08.06.2516:10
Es könnte ein Copy and Paste-Fehler sein. Vielleicht hast du einen Zeilenumbruch zuviel oder das Pipe-Symbol | fehlt. So sollte es formatiert sein, diesmal als Screenshot

Das ist das gleiche Skript ohne Kommentare und ohne die überflüssige Zeile (subfolder_name ...)

Wenn deine Orderstruktur so aussieht


Dann startest Du das Skript mit dem Foto-Verzeichnis, also z.B.
./flatten.sh /Volumes/home/Routinentest/Foto
+1
sudoRinger
sudoRinger08.06.2516:38
Kehrblech
Ist die Pfadangabe falsch? Diese habe ich per <alt> + klick aus dem Finder kopiert.
Am Pfad liegt es m.E. nicht, da Syntax-Fehler gemeldet werden: "command not found"

Stelle sicher, dass bei deinem Texteditor Line Endings auf LF (Unix) stehen und nicht auf "Windows".
+1
Kehrblech08.06.2517:11
Diesmal habe ich es mit deinem neuen Skript versucht. Das Ergebnis war anders, aber noch nicht befriedigend. Zwar ist alles gut durchgelaufen:
MacBook-Pro-M1 ~ % ./flattenfolders.sh /Volumes/home/Routinentest/2
Bearbeite: /Volumes/home/Routinentest/2/2009/01/07
Bearbeite: /Volumes/home/Routinentest/2/2009/01/11
Bearbeite: /Volumes/home/Routinentest/2/2009/01/13
Bearbeite: /Volumes/home/Routinentest/2/2009/01/15
Bearbeite: /Volumes/home/Routinentest/2/2009/01/16
Bearbeite: /Volumes/home/Routinentest/2/2009/01/18
Bearbeite: /Volumes/home/Routinentest/2/2009/01/20
Bearbeite: /Volumes/home/Routinentest/2/2009/01/22
Bearbeite: /Volumes/home/Routinentest/2/2009/01/23
Bearbeite: /Volumes/home/Routinentest/2/2009/01/25
Bearbeite: /Volumes/home/Routinentest/2/2009/01/26
Bearbeite: /Volumes/home/Routinentest/2/2009/01/28
Bearbeite: /Volumes/home/Routinentest/2/2009/01/29
Bearbeite: /Volumes/home/Routinentest/2/2009/01/31
Fertig!
Doch an den Dateien in den Ordnern hat sich rein gar nichts getan. Die obigen Tage-Ordner wie z.B. /Volumes/home/Routinentest/2/2009/01/31 enthalten noch sämtliche Unterordner samt Fotos, während auf die Tagesebene nicht ein Foto verschoben wurde.
Mein Skript sieht jetzt so aus:

Habe gerde gesehen, das dort rndir statt rmdir angekommen ist.
Die Line endings standen übrigens auf "macOS / Unix".
0
Kehrblech08.06.2517:25
Das Null-Ergebnis mit dem korrigierten Skript bleibt leider das gleiche.
0
sudoRinger
sudoRinger08.06.2517:34
Das find in Zeile 5 ist in der falschen Zeile (es gehört an den Anfang von Zeile 6). Die Zeile 5 musshinter do mit einem Zeilenumbruch enden.
Du hast einen Unterstrich statt Bindestrich in "*-*". Dadurch arbeitet das Skript alle Tagesordner ab, aber kein Unterordner war ein Treffer.
Du kannst wie gesagt -name "*-*" auch weglassen, wenn alle Unterordner unabhängig von Namen aufgelöst werden sollen.
+1
Kehrblech08.06.2517:44
Danke für die Korrektur!
Jetzt haben sich die Bilder bewegt. Die alten Ordner sind allerdings noch erhalten. Sie sind aber leer, stören von daher nicht weiter.
0
sudoRinger
sudoRinger08.06.2517:50
Kehrblech
Die alten Ordner sind allerdings noch erhalten.
ok, das könnte an versteckten Dateien wie .DS_Store liegen. Ersetze die Zeile mit rmdir durch
rm -rf "$subfolder" 2>/dev/null
dann löscht es auch die Unterordner mit versteckten Dateien.

Edit: Auch .@__thumb wird damit erledigt.
0
Kehrblech08.06.2517:50
In der File Station wird pro nicht gelöschtem Unterordner noch ein weiterer Unterordner mit dem Namen ".@__thumb" angezeigt, der allerdings leer ist. Ich vermute, der Ordner hat mit der File Station zu tun.
0
Kehrblech08.06.2519:50
Größten Dank nochmal an sudoRinger!
Inzwischen habe ich einfach meine Fotomediathek mit dem Skript aufgeräumt. Die leeren Ordner stören mich, wie gesagt, nicht.
Jetzt sieht alles wieder ordentlicher aus!
0

Kommentieren

Sie müssen sich einloggen, um sich an einer Diskussion beteiligen zu können.