kreuzberger

Ordner zerteilen in mehrere Teile mit vorgegebener Größe

Mahlzeit Digitalfreunde,

ich hatte sowas ähnliches schon mal gefragt, finde es aber hier nicht mehr.

Ich möchte einen Ordner mit Daten in mehrere Teile zerlegen, deren Größe ich vorgebe.

Idee: Da sind 150GB Daten in einer Ordner-Baumstruktur, und die sollen auf 3 x 64GB USB Stick Platz finden.
Lege er mir also von Ordnersomit Ornder-Teil1 (64GB), Ordner-Teil2 (64GB) und Ordner-Teil3 (rest) an.

Mit robocopy ohne script drumherum wird es nicht gehen. Ich finde aber auch keinen Ansatz, wie man das machen könnte. Es müsste ja bei (hier) 64GB einen Abbruch/Unterbrechnung geben. Das sehen aber die parameter von robocopy nicht vor.

Hat da jemand eine Idee, oder gar das perfectescript parat?

Danke, frohe Ostern.

Kreuzberger
Auf Facebook teilen
Auf X (Twitter) teilen
Auf Reddit teilen
Auf Linkedin teilen

Content-ID: 672558

Url: https://administrator.de/forum/ordner-zerteilen-in-mehrere-teile-mit-vorgegebener-groesse-672558.html

Ausgedruckt am: 12.05.2025 um 22:05 Uhr

CH3COOH
CH3COOH 20.04.2025 um 15:31:29 Uhr
Goto Top
Hey,
was spricht von Einsatz eines Werkzeuges wie zum Beispiel WinRAR ?
https://www.win-rar.com/start.html?&L=1

Du packst deinen Ordner ohne Kompression (Speichern) und lässt bequem die Zielgröße für die Blöcke definieren..

Gruß
kreuzberger
kreuzberger 20.04.2025 um 15:33:59 Uhr
Goto Top
@CH3COOH

Danke

Ich will ja nichts komprimieren bzw. in gepackte Files versammeln. 7zip, winrar etc. können das. Aber das ist ja packen und koprimieren, nicht einfach nur kopieren.

Kreuzberger
BiberMan
BiberMan 20.04.2025 aktualisiert um 17:20:45 Uhr
Goto Top
$SourceFolder = "D:\Source"  
$DestinationRoot = "D:\Destination"  
$maxSize = 64GB
# ========
$fldrSize = 0
$FolderIndex = 1

foreach($file in Get-ChildItem -Path $SourceFolder -File -Recurse | sort-object Length){
    if ($file.Length + $fldrSize -gt $maxSize) {
        $FolderIndex++
        $fldrSize = 0
    }
    $CurrentFolderPath = Join-Path $DestinationRoot "Part-$('{0:D2}' -f $FolderIndex)$(split-path ($file.Fullname -replace ([regex]::Escape($sourceFolder))) -parent)"  
    if (!(Test-Path $currentFolderPath -PathType Container)){
        New-Item -ItemType Directory -Path $CurrentFolderPath -Force | Out-Null
    }
    Copy-Item -Path $file.FullName -Destination $CurrentFolderPath
    $fldrSize += $file.Length
}
Edit: Typo korrigiert

tio.run-Demo

Zur Info: Die Ordnerstruktur des Quellordners wird in den "Part"-Ordnern beibehalten.
kreuzberger
kreuzberger 20.04.2025 um 16:29:37 Uhr
Goto Top
@BiberMan

WOW, klasse!

Ich probiere das gleich nachher mal aus. Bin hier gerade auf einem MAC (kein Power-Shell).
Ist das jetzt eine KI-generierte Lösung?

Kreuzberger
BiberMan
BiberMan 20.04.2025 aktualisiert um 16:35:28 Uhr
Goto Top
Zitat von @kreuzberger:
Ist das jetzt eine KI-generierte Lösung?
Never ever kommt mir KI fürs Programmieren in die Finger...
Meine Skripte sind alle noch echte Handarbeit.
kreuzberger
kreuzberger 20.04.2025 um 16:54:05 Uhr
Goto Top
@BiberMan

👍👍👍👍👍👍👍👍👍👍👍👍👍

Kreuzberger
knurrhahn
knurrhahn 20.04.2025 um 17:02:00 Uhr
Goto Top
Ist das jetzt eine KI-generierte Lösung?

Die sähe von ChatGPT so aus face-smile :

Zitat:

@echo off
setlocal EnableDelayedExpansion

:: === KONFIGURATION ===
set "SOURCE=C:\Pfad\zu\Quelle"  
set "DEST_BASE=D:\Ziel\Verzeichnis"  
set "MAX_SIZE_MB=4096"  
set "CURRENT_PART=1"  

:: Erstellt eine Liste aller Dateien
set "FILE_LIST=%TEMP%\filelist.txt"  
dir /b /s /a:-d "%SOURCE%" > "%FILE_LIST%"  

:: Initialisiere Zielverzeichnis
call :InitNextDestination

:: Hauptschleife über alle Dateien
for /f "usebackq delims=" %%F in ("%FILE_LIST%") do (  
    set "FILE=%%F"  
    
    :: Datei-Größe in Byte holen
    for %%A in ("!FILE!") do set "SIZE=%%~zA"  

    :: Zielgröße prüfen
    call :GetDirSize "!DEST!" CURRENT_SIZE  

    set /a TOTAL_SIZE=!CURRENT_SIZE! + !SIZE!

    :: Überschreitet MAX_SIZE_MB?
    set /a MAX_SIZE_BYTES=%MAX_SIZE_MB% * 1048576
    if !TOTAL_SIZE! GEQ !MAX_SIZE_BYTES! (
        set /a CURRENT_PART+=1
        call :InitNextDestination
    )

    echo Kopiere !FILE! nach !DEST!
    robocopy /njh /njs /nc /ns /np /mov /R:0 /W:0 "!SOURCE!" "!DEST!" "!FILE:%SOURCE%\=!" >nul  
)

:: Aufräumen
del "%FILE_LIST%"  
echo Kopiervorgang abgeschlossen.
exit /b


:: === FUNKTION: Initialisiere nächstes Zielverzeichnis ===
:InitNextDestination
set "DEST=%DEST_BASE%%CURRENT_PART%"  
if not exist "!DEST!" mkdir "!DEST!"  
goto :eof

:: === FUNKTION: Hole Gesamtgröße des Zielverzeichnisses in Bytes ===
:GetDirSize
setlocal
set "DIR=%~1"  
set "VAR=%~2"  
set "SIZE=0"  

for /f "tokens=3" %%S in ('dir /s /-c "%DIR%" ^| find "Datei(en)"') do (  
    set "SIZE=%%S"  
)

:: Entferne Punkte aus Zahlenformat (z. B. 1.234.567 → 1234567)
set "SIZE=%SIZE:.=%"  

endlocal & set "%VAR%=%SIZE%"  
goto :eof

Zitat Ende.

@BiberMan: Es lebe die Handarbeit!

Gruß
knurrhahn
Pjordorf
Pjordorf 20.04.2025 um 20:11:05 Uhr
Goto Top
TK1987
TK1987 22.04.2025 aktualisiert um 12:51:33 Uhr
Goto Top
Moin,

Zitat von @kreuzberger:
Idee: Da sind 150GB Daten in einer Ordner-Baumstruktur, und die sollen auf 3 x 64GB USB Stick Platz finden.
Zitat von @BiberMan:
$maxSize = 64GB
hier gilt es natürlich zu beachten, das bei Powershell Windowsüblich als Einheit Gibibyte statt Gigabyte verwendet wird und 64 GiB nicht auf einen 64GB USB-Stick passen. Die Größe müsste also angepasst werden...
$maxSize = 59.6GB

Gruß Thomas
kreuzberger
kreuzberger 22.04.2025 um 13:07:16 Uhr
Goto Top
@TK1987

Danke für den wertvollen Hinweis.

Gäbe es da nicht die Möglichkeit, bei der Eingabe der Maximalen Teil-Größe eine Umrechnung in das Script einzubauen?
Wir sollte man das pfiffigerweise machen?

Kreuzberger
TK1987
TK1987 22.04.2025 aktualisiert um 14:04:08 Uhr
Goto Top
Zitat von @kreuzberger:
Gäbe es da nicht die Möglichkeit, bei der Eingabe der Maximalen Teil-Größe eine Umrechnung in das Script einzubauen?
Man könnte gleich in GB rechnen. Ich würde aber zur Sicherheit noch ein wenig abziehen, da die Sticks oft etwas kleiner sind als angegeben. Daher noch mal mit 0,96 multipliziert...
$maxSizeGB = 64
# ========
$maxSize = $maxSizeGB * 0.96 * [math]::pow(10,9)
So sollte es dann auf jeden Fall drauf passen.