konkretor
Artikeldetektiv
- Registriert
- März 2011
- Beiträge
- 7.222
Nutze doch mal Claude als Alternative
https://claude.ai
https://claude.ai
Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: Diese Funktion ist in einigen Browsern möglicherweise nicht verfügbar.
Im Anhang habe ich 2 txt-Dateien hochgeladen. Einmal eine namens "output.txt" und einmal eine namens "search.txt". Die output.txt-Datei ist vollständig, die search.txt-Datei enthält beispielhaft aufgrund der Größenbeschränkung nur einen Teil der Inhalte, ist aber in Wirklichkeit viel größer. Die search.txt-Datei fungiert als Indexdatei, die Pfade zu verschiedenen Medientypen auf dem PC enthält.
Folgendes Vorhaben:
Die output.txt-Datei enthält konkrete Pfade zu Medien. Diese konkreten Medien der output-Datei sollen anhand der Speicherorte der search.txt-Datei (Index-Datei) gefunden und in einen neuen Ordner namens "gefunden" kopiert werden. Es soll dabei das Ordnerverzeichnis der Output-Textdatei auch im "gefunden"-Ordner für die gefundenen Kopien beibehalten werden. Das heißt, die Verzeichnisstruktur ab dem Ordner "Media" und dessen Unterordner soll beibehalten werden. Desweiteren soll das Script Dateien, welche vom Dateinamen identisch sind, berücksichtigen, aber nur dann kopieren, wenn sich der Inhalt aller doppelten Dateien unterscheidet.
Ein konkretes Beispiel hierfür, um es nachvollziehen zu können:
In der Output-Textdatei befindet sich z.B. ein Eintrag Media/WhatsApp Images/IMG-20160519-WA0000.jpg
Ist nun diese Datei "IMG-20160519-WA0000.jpg" anhand der Index-Datei mehrfach in verschiedenen Verzeichnissen vorhanden, soll diese Datei kopiert werden und zudem alle weiteren Dateien mit demselben Dateinamen, die sich inhaltlich (Größe, Hashwerte) von ihr unterscheiden. Wenn es keine inhaltlichen Unterschiede gibt, soll nur eine Instanz kopiert werden. Wenn es inhaltliche Unterschiede zwischen gefundenen Dateien mit identischem Dateinamen gibt, dann sollen all jene Dateien kopiert werden, die sich jeweils inhaltlich durch Hashwerte voneinander unterscheiden. Damit sich diese Dateien im "gefunden-Ordner" nicht gegenseitig überschreiben, soll dann an den Dateinamen am Ende für jede weitere Kopie ein (1), (2), etc. angehängt werden.
import os
import shutil
import hashlib
# Pfade zu den Dateien
output_file = 'output.txt'
search_file = 'search.txt'
zielordner = 'gefunden'
# Hilfsfunktion: Hash einer Datei berechnen
def calculate_file_hash(filepath, chunk_size=8192):
hasher = hashlib.md5()
with open(filepath, 'rb') as f:
for chunk in iter(lambda: f.read(chunk_size), b""):
hasher.update(chunk)
return hasher.hexdigest()
# Output- und Search-Dateien einlesen
with open(output_file, 'r', encoding='utf-8') as f:
output_paths = [line.strip() for line in f if line.strip()]
with open(search_file, 'r', encoding='utf-8') as f:
search_paths = [line.strip() for line in f if line.strip()]
# Mapping der Dateien nach Dateinamen
search_dict = {}
for full_path in search_paths:
filename = os.path.basename(full_path)
if filename not in search_dict:
search_dict[filename] = []
search_dict[filename].append(full_path)
# Zielordner erstellen
os.makedirs(zielordner, exist_ok=True)
# Dateien aus der Output-Liste verarbeiten
for relative_path in output_paths:
filename = os.path.basename(relative_path)
subfolder = os.path.dirname(relative_path)
# Überprüfen, ob Datei in der Search-Datei existiert
if filename in search_dict:
found_files = search_dict[filename]
# Hashes aller gefundenen Dateien berechnen
hashes = {}
for file_path in found_files:
file_hash = calculate_file_hash(file_path)
if file_hash not in hashes:
hashes[file_hash] = []
hashes[file_hash].append(file_path)
# Dateien kopieren, unter Berücksichtigung von Duplikaten
for i, (file_hash, paths) in enumerate(hashes.items()):
source_path = paths[0] # Nur eine Instanz je Hash kopieren
# Zielverzeichnis und -dateiname vorbereiten
target_subfolder = os.path.join(zielordner, subfolder)
os.makedirs(target_subfolder, exist_ok=True)
if i == 0:
target_path = os.path.join(target_subfolder, filename)
else:
name, ext = os.path.splitext(filename)
target_path = os.path.join(target_subfolder, f"{name}({i}){ext}")
# Datei kopieren
shutil.copy2(source_path, target_path)
print("Dateien wurden erfolgreich verarbeitet und kopiert.")
import os
# Quellordner definieren
source_dirs = [
r"D:\Backup Handys + WhatsApp Medien"
]
# Zieldatei für die Ergebnisse
output_file = "search.txt"
# Suchbegriffe
keywords = ["WA0", "s.whatsapp.net", "g.us"]
# Funktion zum Durchsuchen der Ordner
def search_files(source_dirs, keywords, output_file):
results = []
for source_dir in source_dirs:
if not os.path.exists(source_dir):
print(f"Ordner '{source_dir}' existiert nicht.")
continue
# Durchlaufe alle Dateien in diesem Ordner und Unterordnern
for root, _, files in os.walk(source_dir):
for file in files:
if any(keyword in file for keyword in keywords):
full_path = os.path.join(root, file)
results.append(full_path)
print(f"Gefunden: {full_path}")
# Ergebnisse in die Datei schreiben
with open(output_file, "w", encoding="utf-8") as f:
for line in results:
f.write(line + "\n")
print(f"Fertig. Ergebnisse sind in '{output_file}' gespeichert.")
# Hauptfunktion ausführen
if __name__ == "__main__":
search_files(source_dirs, keywords, output_file)
print("Copy " + source_path + " to " + target_path)
.name_with_counter = name + "(" + str(i) + ")." + ext
target_path = os.path.join(target_subfolder, name_with_counter)
simpsonsfan schrieb:Aus dem Kopf raus könnte ich jetzt nicht sagen, ob Zeile 54 funktioniert (ob das enumerate wirklich ein Tupel für das dict ausspuckt), aber kannst du ja testen.
simpsonsfan schrieb:Und deine output.txt sollte dann wohl Relativpfade enthalten. (Also relativ zu deiner gewünschten Struktur, ohne Laufwerksbuchstaben.)
simpsonsfan schrieb:Generell kannst du dir bei (vor oder nach) Zeile 68 noch eine Textausgabe geben lassen, die dir mitteilt, welche Dateien kopiert wurden. Also etwaprint("Copy " + source_path + " to " + target_path)
.
simpsonsfan schrieb:Außerdem könnte es sein, das in dem Formatstring in Zeile 65 der Punkt fehlt. Bin mir da grade nicht sicher. Ich hätte vermutlich
geschrieben. Aber das ist rein persönliche Vorliebe. Eigentlich sind Formatstring evtl. sogar besser lesbar.Python:name_with_counter = name + "(" + str(i) + ")." + ext target_path = os.path.join(target_subfolder, name_with_counter)
simpsonsfan schrieb:Ich vermute übrigens, dass das eine Weile laufen könnte.
simpsonsfan schrieb:Schöner wäre evtl. auch, die Hashes schon bei der Indizierung der Backupdateien zu berechnen (und zu speichern.)
simpsonsfan schrieb:Aber ich würde sagen, einfach mal testen.