Dateien in verschiedenen Ordnern ersetzen

German support forum

Moderators: Hacker, Stefan2, white

User avatar
Kerstin83
Senior Member
Senior Member
Posts: 341
Joined: 2007-11-25, 10:18 UTC
Location: Hannover

Dateien in verschiedenen Ordnern ersetzen

Post by *Kerstin83 »

Liebes Forum :) :)

Wenn ich in meinem cms-System zum Beispiel das Bild "bild1.jpg" hochlade, dann werden automatisch verschiedene Thumbnails erzeugt (bild1_100x100.jpg, bild1_200x200.jpg u.s.w.). Diese Thumbnails werden dann in Ordner gelegt, die den ersten 6 Zeichen des md5-Codes des Dateinamens entsprechen. Das sieht dann so aus (Werte sind erfunden):

ae/b1/c2/bild1.jpg
e1/2b/3f/bild1_100x100.jpg
c4/f1/21/bild1_200x200.jpg

(das wurde so gemacht, damit die Ordner nicht zu viele Dateien beherbergen müssen).

Nun möchte ich die Tumbnails von bild1 gegen Bilder austauschen, die auf meinem PC in einem Ordner liegen. Das ist ziemlich kompliziert, weil ich ja erst das md5 berechnen müsste und dann in die Ordner gehen müsste, was wirklich sehr mühselig wäre.

Gibt es im Totalcommander eine Möglichkeit, das irgendwie einfacher zu machen ? Zum Beispiel nach bild1 zu suchen und dann irgendwie zu ersetzen.

Wenn es für FTP keine Möglichkeit gibt, gibt es dann vielleicht eine direkte (also Verzeichnisse auf PC) ? Damit käme ich auch etwas weiter.

Liebe Grüße

Kerstin
Ich hasse Leute, die Sätze nicht zuende
User avatar
Hacker
Moderator
Moderator
Posts: 13142
Joined: 2003-02-06, 14:56 UTC
Location: Bratislava, Slovakia

Post by *Hacker »

Hallo Kerstin83,
Hast Du denn die neuen 100x100, 200x200, usw. Thumbnails parat oder müssen die noch aus dem neuen Bild1 erstellt werden?

Roman
Mal angenommen, du drückst Strg+F, wählst die FTP-Verbindung (mit gespeichertem Passwort), klickst aber nicht auf Verbinden, sondern fällst tot um.
User avatar
Kerstin83
Senior Member
Senior Member
Posts: 341
Joined: 2007-11-25, 10:18 UTC
Location: Hannover

Post by *Kerstin83 »

Die habe ich parat und sie sind alle in einem Ordner auf dem PC. Und sie heißen genau so wie die Dateien, die ausgetauscht werden sollen.
Ich hasse Leute, die Sätze nicht zuende
User avatar
Stefan2
Power Member
Power Member
Posts: 4281
Joined: 2007-09-13, 22:20 UTC
Location: Europa

Post by *Stefan2 »

Fragen zur Klärung:


1) Es existieren mehrere Tumbnails von jedem Fullsize Bild, wie zB bild1 ?

2) und diese können in verschieden Ordnern vorkommen?

e1/2b/3f/bild1_100x100.jpg
c4/f1/21/bild1_200x200.jpg
xy/2b/3f/bild1_100x100.jpg
zdf/f1/21/bild1_200x200.jpg



3) Die Fullsize Bilder wie zB bild1 sind alle in einem bestimmten Ordner?


4) Außer dem Namen
- bild1.jpg
- bild1_<ZAHL>x<ZAHL>.jpg
gibt es keinen Zusammenhang zwischen den Speicherordnern?

Also, alles vor dem ersten Unterstrich ist tatsächlich bei Fullsize und Tumbnail gleich?



5) Man müsste also entweder zu jedem bild1.jpg die passenden
bild1_<ZAHL>x<ZAHL>.jpg Dateien suchen und austauschen,

oder umgekehrt, nach <xyz>_<ZAHL>x<ZAHL>.jpg suchen
und dann schauen ob ein <xyz>.jpg existiert?



?
User avatar
Hacker
Moderator
Moderator
Posts: 13142
Joined: 2003-02-06, 14:56 UTC
Location: Bratislava, Slovakia

Post by *Hacker »

Kerstin83,
Ein kurzes AHK Skript. ;) Kopiert alle Dateien im aktuellen Verzeichnis in Unterverzeichnisse die es nach dem MD5 Schema erstellt.

Code: Select all

Loop, Files, *.*
{
	Dir := SubStr(MD5(SubStr(A_LoopFileName, 1, 6)), 1, 2) . "\" . SubStr(MD5(SubStr(A_LoopFileName, 1, 6)), 3, 2) . "\" . SubStr(MD5(SubStr(A_LoopFileName, 1, 6)), 5, 2)
	FileCreateDir, %Dir%
	FileCopy, %A_LoopFileName%, %Dir%\%A_LoopFileName%
}

MD5(ByRef V, L := 0)
{
	VarSetCapacity(MD5_CTX, 104, 0)
	DllCall("advapi32\MD5Init", Str, MD5_CTX)
	DllCall("advapi32\MD5Update", Str, MD5_CTX, Str, V, UInt, L ? L : VarSetCapacity(V))
	DllCall("advapi32\MD5Final", Str, MD5_CTX)
	Loop, % StrLen(Hex := "123456789ABCDEF0")
	{
		N := NumGet(MD5_CTX, 87+A_Index, "Char")
		MD5 .= SubStr(Hex, N>>4, 1) . SubStr(Hex, N&15, 1)
	}
	Return, MD5
}
EDIT: MD5 Code von hier geklaut.

HTH
Roman
Mal angenommen, du drückst Strg+F, wählst die FTP-Verbindung (mit gespeichertem Passwort), klickst aber nicht auf Verbinden, sondern fällst tot um.
User avatar
Kerstin83
Senior Member
Senior Member
Posts: 341
Joined: 2007-11-25, 10:18 UTC
Location: Hannover

Post by *Kerstin83 »

cool, hört sich gut an. Danke. Aber wie genau kann ich das Skript starten?

(Ich glaube ich habe so etwas schon einmal gemacht, stehe aber im Augenblick etwas auf dem Schlauch)

Liebe Grüße

Kerstin
Ich hasse Leute, die Sätze nicht zuende
User avatar
Hacker
Moderator
Moderator
Posts: 13142
Joined: 2003-02-06, 14:56 UTC
Location: Bratislava, Slovakia

Post by *Hacker »

Kerstin83,
AutoHotkey installieren, den [ code ] als Bild.ahk speichern und ausführen.

HTH
Roman
Mal angenommen, du drückst Strg+F, wählst die FTP-Verbindung (mit gespeichertem Passwort), klickst aber nicht auf Verbinden, sondern fällst tot um.
User avatar
Kerstin83
Senior Member
Senior Member
Posts: 341
Joined: 2007-11-25, 10:18 UTC
Location: Hannover

Post by *Kerstin83 »

Vielen Dank, das geht schon in die richtige Richtung. Allerdings 2 Schönheitsfehler:

1. Es wird der Vollständige Name des Bildes inclusive des angehängten z.b. _100x100 und auch inclusive Punkt und Dateiendung verwendet. bild1_100x100.jpg ist in einem völlig anderen Ordner als bild1.jpg.
(das innere Substring war also nicht nötig)

2. Was ich nicht wusste, es wird auch ein Teil des Pfades verwendet. Im Normalfall ist das media/image/ und man könnte dies als Konstante nehmen (oder man müsste im Pfad nach media suchen und den Pfad ab diesem nehmen). Das md5 müsste also von dem String
media/image/bild1.jpg etc. gebildet werden.

Hier mal echte Pfade
media/image/bild1.jpg -> md5 =cca136a8554d11c2506f40e4d0bb78ba. Liegt also hier: cc/a1/36/bild1.jpg

media/image/bild1_100x100.jpg -> md5 =70b8a7cbafcfe17d0fdfb52570b6d705. Liegt also hier: 70/b8/a7/bild1_100x100.jpg

Ich habe das mal angepasst:

Code: Select all

Loop, Files, *.* 
{ 
   String:="media/image/" . A_LoopFileName
   MD5String:=MD5(String)
   Dir := SubStr(MD5String, 1, 2) . "\" . SubStr(MD5String, 3, 2) . "\" . SubStr(MD5String, 5, 2) 
   FileCreateDir, %Dir% 
   FileCopy, %A_LoopFileName%, %Dir%\%A_LoopFileName% 
} 

MD5(ByRef V, L := 0) 
{ 
   VarSetCapacity(MD5_CTX, 104, 0) 
   DllCall("advapi32\MD5Init", Str, MD5_CTX) 
   DllCall("advapi32\MD5Update", Str, MD5_CTX, Str, V, UInt, L ? L : VarSetCapacity(V)) 
   DllCall("advapi32\MD5Final", Str, MD5_CTX) 
   Loop, % StrLen(Hex := "123456789abcdef0") 
   { 
      N := NumGet(MD5_CTX, 87+A_Index, "Char") 
      MD5 .= SubStr(Hex, N>>4, 1) . SubStr(Hex, N&15, 1) 
   } 
   Return, MD5 
}
Das liefert allerdings auch falsche Ordner. Ich habe den Eindruck, dass der md5-Code nicht korrekt gebildet wird. Auch bei anderen, ganz simplen Strings liefert das ganz andere md5 als andere md5-Generatoren. Habe ich da etwas falsch gemacht? Oder ist vielleicht an der Funktion md5 etwas nicht in Ordnung?
:(

Liebe Grüße

Kerstin :)
Ich hasse Leute, die Sätze nicht zuende
User avatar
Hacker
Moderator
Moderator
Posts: 13142
Joined: 2003-02-06, 14:56 UTC
Location: Bratislava, Slovakia

Post by *Hacker »

Hallo Kerstin83,
1. Es wird der Vollständige Name des Bildes inclusive des angehängten z.b. _100x100 und auch inclusive Punkt und Dateiendung verwendet. bild1_100x100.jpg ist in einem völlig anderen Ordner als bild1.jpg.
(das innere Substring war also nicht nötig)
Hast recht, habe die Aufgabe falsch verstanden.
Ich habe den Eindruck, dass der md5-Code nicht korrekt gebildet wird. [...] ist vielleicht an der Funktion md5 etwas nicht in Ordnung?
Hast auch recht.

Dieser Code funktioniert jetzt hoffentlich:

Code: Select all

Loop, Files, *.*
{
	MD5HashedFileName := MD5("media/image/" . A_LoopFileName)
	Dir := SubStr(MD5HashedFileName, 1, 2) . "\" . SubStr(MD5HashedFileName, 3, 2) . "\" . SubStr(MD5HashedFileName, 5, 2)
	FileCreateDir, %Dir%
	FileCopy, %A_LoopFileName%, %Dir%\%A_LoopFileName%
}

MD5(String, Case := False) ; by SKAN | rewritten by jNizM
{
	hModule := DllCall("LoadLibrary", "Str", "advapi32.dll", "Ptr")
	VarSetCapacity(MD5_CTX, 104, 0)
	DllCall("advapi32\MD5Init", "Ptr", &MD5_CTX)
	DllCall("advapi32\MD5Update", "Ptr", &MD5_CTX, "AStr", String, "UInt", StrLen(String))
	DllCall("advapi32\MD5Final", "Ptr", &MD5_CTX)
	Loop, 16
		MD5Hash .= Format("{:02" (Case ? "X" : "x") "}", NumGet(MD5_CTX, 87 + A_Index, "UChar"))
	DllCall("FreeLibrary", "Ptr", hModule)
	Return, MD5Hash
}
MD5 Code geklaut von hier.

HTH
Roman
Mal angenommen, du drückst Strg+F, wählst die FTP-Verbindung (mit gespeichertem Passwort), klickst aber nicht auf Verbinden, sondern fällst tot um.
User avatar
Kerstin83
Senior Member
Senior Member
Posts: 341
Joined: 2007-11-25, 10:18 UTC
Location: Hannover

Post by *Kerstin83 »

Vielen Dank :)

Läuft schon viel besser. In vielen Fällen funktioniert es jetzt, zum Beispiel bild1.jpg wird richtig abgelegt.
Aber merkwürdiger Weise ist aber ca die Hälfte wieder falsch :(. MD5 ist schon recht kompliziert.
Ein Beispiel:
media/image/bild1_140x140.jpg
wird in diesen Ordner gelegt -> cf/80/93/bild1_140x140.jpg
richtig wäre: 68/62/b6/bild1_140x140.jpg

Vielleicht liegt es an bestimmten Zeichen (Unterstrich) oder so?

Ich habe das hier gefunden
https://github.com/jNizM/AutoHotkey_Scripts/blob/master/Functions/Checksums/MD5.ahk

funktioniert aber leider auch nicht richtig.

Liebe Grüße

Kerstin
Ich hasse Leute, die Sätze nicht zuende
User avatar
ZoSTeR
Power Member
Power Member
Posts: 1050
Joined: 2004-07-29, 11:00 UTC

Post by *ZoSTeR »

Hier mal in PowerShell:

Code: Select all

function Main
{
    $sourceFolder = "c:\Images\"
    $stringBeforeName = "media/image/"
    $files = Get-ChildItem -Path $sourceFolder
    foreach ($file in $files)
    {
        $hash = Hash -textToHash ($stringBeforeName + $file.Name)
        $destinationFolder =  $sourceFolder + "\" + $hash.Substring(0,2) + "\" + $hash.Substring(2,2) + "\" + $hash.Substring(4,2) + "\"
        New-Item -Path $destinationFolder -ItemType Directory
        Copy-Item -Path $file.FullName -Destination $destinationFolder
    }
}

function Hash($textToHash)
{
    $hasher = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
    $toHash = [System.Text.Encoding]::UTF8.GetBytes($textToHash)
    $hashByteArray = $hasher.ComputeHash($toHash)
    foreach($byte in $hashByteArray)
    {
         $res += '{0:x2}' -f $byte
    }
    return $res;
}

Main
Edit: Führende Null im Hex-Wert korrigiert
Last edited by ZoSTeR on 2015-11-08, 15:04 UTC, edited 1 time in total.
User avatar
Hacker
Moderator
Moderator
Posts: 13142
Joined: 2003-02-06, 14:56 UTC
Location: Bratislava, Slovakia

Post by *Hacker »

Hallo Kerstin83,
media/image/bild1_140x140.jpg
wird in diesen Ordner gelegt -> cf/80/93/bild1_140x140.jpg
richtig wäre: 68/62/b6/bild1_140x140.jpg
Bei mir funktioniert es richtig, bild1_140x140.jpg wird nach 68\62\b6 kopiert. Kannst Du das bitte nochmals überprüfen und bestätigen?

Roman
Mal angenommen, du drückst Strg+F, wählst die FTP-Verbindung (mit gespeichertem Passwort), klickst aber nicht auf Verbinden, sondern fällst tot um.
User avatar
Kerstin83
Senior Member
Senior Member
Posts: 341
Joined: 2007-11-25, 10:18 UTC
Location: Hannover

Post by *Kerstin83 »

sorry, du hast recht, es funktioniert einwandfrei. Vielen Dank. Habe mich da vertan.

Es ist so, dass die Ablage im cms System doch noch ein bisschen anders ist. Bei den Originalbilder (bild1.jpg) funktioniert es wie beschrieben. Aber bei den Thumbnails (bild1_140x140.jpg etc) kommt noch der Ordner 'thumbnail' dazu; das md5 wird von 'media/image/thumbnail/bild1_140x140.jpg' gebildet. Das wusste ich nicht. Ist auch nicht dokumentiert. Diese Dateiablage ist echt krank. :(

Ich habe das jetzt noch eingefügt. Jetzt klappt es.

Kann man - ohne viel Mühe - vielleicht doch irgendwie den Ordner abrfragen?
An den Dateien kann man leider nicht eindeutig erkennen, ob es sich um ein Thumbnail handelt, der Unterstrich kann ja auch so einmal vorkommen.

Im Augenblick habe ich das ahk-Skript im jeweiligen Ordner und wird dann auch kopiert. Irgendwie konnte man doch ahk-Skripte in die Topleiste legen und dann von dort aus starten.

Danke auch für das Power Shell Prog.
Ich hasse Leute, die Sätze nicht zuende
User avatar
Hacker
Moderator
Moderator
Posts: 13142
Joined: 2003-02-06, 14:56 UTC
Location: Bratislava, Slovakia

Post by *Hacker »

Kerstin83,
Kann man - ohne viel Mühe - vielleicht doch irgendwie den Ordner abrfragen?
Was meinst Du genau? Ob im aktuellen Pfad ein "thumbnail" vorkommt? Oder?

Roman
Mal angenommen, du drückst Strg+F, wählst die FTP-Verbindung (mit gespeichertem Passwort), klickst aber nicht auf Verbinden, sondern fällst tot um.
User avatar
Kerstin83
Senior Member
Senior Member
Posts: 341
Joined: 2007-11-25, 10:18 UTC
Location: Hannover

Post by *Kerstin83 »

Die Bilddatei liegt ja in dem Ordner media/image bzw. im Ordner media/image/thumbnail. Und andere Dateien (z.B. pdf) werden analog abgelegt. Es wäre praktisch, wenn man den kompletten Pfad ab media nehmen würde. Wenn das mit einfachen Mitteln zu machen ist. Ansonsten könnte man prüfen, ob thumbnail vorkommt und dann einfach noch einfügen. Ich kann die Sprache ahk leider nicht :(

Aber das andere ist auch wichtig, wie ich noch mal diesen Botton bekomme?
(Ich habe das schon mal gemacht, übrigens auch mit einem AHK-Skript von dir :) Für das bedanke ich mich auch noch einmal!!)

Liebe Grüße

Kerstin
Ich hasse Leute, die Sätze nicht zuende
Post Reply