Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Hilfe zu verschiedenen Themen
Antworten
Viper73
Beiträge: 16
Registriert: 10. Mär 2024 09:33

Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von Viper73 »

Hallo,

Ich habe einige hundert Verzeichnisse, die unnötige Unterverzeichnisse haben, welche ich weg haben möchte. In den Verzeichnissen sind jedoch noch viele Bilder/Dateien enthalten, die ich in den Übergeordneten Ordner verschieben möchte damit diese nicht verloren gehen:

Beispiel aktuell:
D:\Bilder\Ordner1\Unterordner1\datei1.jpg
D:\Bilder\Ordner2\Unterordner2\datei2.jpg
D:\Bilder\Ordner3\Unterordner3\datei3.jpg

Gibt es eine Möglicht dies durch automatisches verschieben bzw. ausschneiden/einfügen (alles auf einmal, zb. per Script) zu erledigen? Also das jeweils der Inhalt von Unterordner(1,2,etc) zum (Übergeordneten) Ordner(1,2,etc) verschoben wird? Die daraus entstehenden leeren Unterordner können bleiben und müssen dabei nicht automatisch gelöscht werden, mir geht es darum die Dateien auf einen Schlag zu verschieben. Aber ich möchte das die Dateien automatisch in eine Verzeichnisebene darunter verschoben werden:

Beispiel nachher:
D:\Bilder\Ordner1\datei1.jpg
D:\Bilder\Ordner2\datei2.jpg
D:\Bilder\Ordner3\datei3.jpg

Ich hoffe ich hab es einigermaßen verständlich erklärt.
Ist das irgendwie durch eine Suchen/Ersetzen Funktion oder ähnlichem in Directory Opus möglich?
Falls nicht, hat zufällig jemand eine Idee wie man sowas sonst relativ einfach lösen könnte?

Gruß, Viper73
Benutzeravatar
josinoro
Supporter
Beiträge: 355
Registriert: 10. Nov 2021 20:56

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von josinoro »

Hallo Viper73,

nachfolgender Schalter verschiebt die Dateien ein Verzeichnis höher. Allerdings musst du dann trotzdem in jedes Verzeichnis gehen.

Code: Alles auswählen

<?xml version="1.0"?>
<button backcol="none" display="both" textcol="#ff8000">
	<label>Nach Oben</label>
	<tip>Aktuellen Ordner zum übergeordneten Ordner verschieben</tip>
	<icon1>#default:goup</icon1>
	<function type="normal">
		<instruction>// Copy MOVE TO=..</instruction>
		<instruction>@Set Folder={sourcepath}</instruction>
		<instruction>Go ..</instruction>
		<instruction>Copy MOVE {$Folder} TO ..  </instruction>
	</function>
</button>
Dann kopiert dieser Schalter alle Objekte eines Ordners in den Zielordner.

Code: Alles auswählen

<?xml version="1.0"?>
<button backcol="none" display="both" textcol="#f9f900">
	<label>Alle Dateien aller Ordner kopieren</label>
	<tip>Kopiert &lt;#ffffff&gt;&lt;b&gt;alle&lt;/b&gt;&lt;/#&gt; angewählten Dateien und &lt;#ffffff&gt;&lt;b&gt;alle&lt;/b&gt;&lt;/#&gt; Dateien unterhalb &lt;#ffffff&gt;&lt;b&gt;aller&lt;/b&gt;&lt;/#&gt; angewählten Ordner in das &lt;#ffffff&gt;Zielverzeichnis&lt;/#&gt;</tip>
	<icon1>#S-DOX Icon Set:folder2_green</icon1>
	<function type="normal">
		<instruction>CopyFlat Move TO={right}</instruction>
	</function>
</button>
Probier die mal aus.
Benutzeravatar
tbone
Supporter
Beiträge: 698
Registriert: 29. Okt 2021 00:45

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von tbone »

Also da fragt man doch das Gemini-Plastikgehirn heutzutage und dann hat man das?! o)..
image.png
image.png (33.04 KiB) 9173779 mal betrachtet

Code: Alles auswählen

# Set the target folder path where your subfolders live
$rootPath = "C:\Your\Target\Folder"

# Get all files inside subfolders, excluding the root folder itself
Get-ChildItem -Path $rootPath -Recurse -File | ForEach-Object {
    # Determine the parent folder of the current file's folder
    $destinationDir = Split-Path (Split-Path $_.DirectoryName -Parent)
    
    # Target path for the file one level up
    $destinationPath = Join-Path $destinationDir $_.Name
    
    # Move the file safely if a file with the same name doesn't exist
    if (-not (Test-Path $destinationPath)) {
        Move-Item -Path $_.FullName -Destination $destinationDir -Force
    } else {
        Write-Warning "Skipped (File already exists): $($_.FullName)"
    }
}
Benutzeravatar
Kundal
Moderator
Beiträge: 168
Registriert: 24. Okt 2021 18:02

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von Kundal »

Hi tbone, deine Plastikhirn-Lösung kopiert im angefragten Fall sämtliche Bilder in D:\Bilder\Ordner(x) eine Ebene höher. Das ist ein wenig zuviel des Guten. Leider kenne ich mich weder mit Plastikgehirnen noch mit Powershell-Skripten aus.

@Josinoro: Dein zweiter Schalter funktioniert so nicht. "CopyFlat " ist vermutlich ein benutzerdefinierter Befehl von dir, jedenfalls kein DOpus-eigener Befehl.

Es sollen hier nur Dateien aus "Unterordner(x)" nach "Ordner(x)" verschoben werden, auf keinen Fall aber auch Dateien von "Ordner(x)" nach "Bilder". Das Ganze soll möglichst mit einem Befehl von der Ebene " Bilder" für alle (markierten) Ordner der Ebene "Ordner" ausgeführt werden, damit man nicht in hunderte Ordner hinein navigieren muss, um den Inhalt der darin enthaltenen Unterordner zu verschieben.
Das ist mit Bordmitteln leider nicht so einfach zu machen. Im Resource Centre habe ich auch nur einen Code gefunden der von der Ebene Unterordner(x) ausgeführt werden muss. Der verschiebt den Inhalt des aktuellen Ordners zum Parent-Ordner und löscht den geleerten Ordner:

Code: Alles auswählen

@set ChildPath={sourcepath$|noterm}
@runmode hide
Copy MOVE * TO ..
Go ..
Delete FILE="{$ChildPath}" NORECYCLE SKIPNOTEMPTY QUIET
Das könnte man vermutlich auch von der Ebene "Ordner(x)" zum Laufen kriegen, bleibt aber mühsam, wenn es viele Ordner(x) gibt. Den Code so umzubauen, dass er von der Ebene "Bilder" funktioniert, ist mir nicht gelungen.

Relativ einfach zu lösen wäre das Problem nur, wenn "Unterordner(x)" immer den gleichen Namen hätte. Dann könnte man auf der Ebene "Bilder" alle gewünschten Ordner auswählen und das hier anwenden (mit Löschen des leeren Unterordners):

Code: Alles auswählen

Copy MOVE {filepath}\Ordnername\*.* TO {filepath}\
Delete FILE="{filepath}\Ordnername" NORECYCLE SKIPNOTEMPTY QUIET
Leider funktioniert das nicht mit einem Wildcard-Platzhalter wie "*" für "Ordnername.
Benutzeravatar
josinoro
Supporter
Beiträge: 355
Registriert: 10. Nov 2021 20:56

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von josinoro »

Hallo Kundal,

du hast recht. Das stammt von hier:
https://resource.dopus.com/t/copyflat-f ... view/44001
Benutzeravatar
Kundal
Moderator
Beiträge: 168
Registriert: 24. Okt 2021 18:02

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von Kundal »

Das hier funktioniert, auch wenn die "Unterordner(x)" beliebige Namen haben. Auszuführen, wenn man sich im aktuellen Ordner "Bilder" befindet und die gewünschten Ordner ausgewählt hat. Die Unterordner der gewählten Ordner werden zuerst nach "Test" umbenannt, dann der Inhalt nach "Ordner(x) verschoben und schließlich der Ordner "Test" gelöscht.
Wenn mehrere Unterordner vorhanden sind, wird nur der Inhalt des ersten Unterordners verschoben, die weiteren Unterordner werden nach "Test (1), Test (2)..." umbenannt. Dann sollte es funktionieren, wenn man den Befehl mehrfach wiederholt, um die weiteren Unterordner (und Unter-Unterordner?) ebenfalls zu erwischen.
Weitere mögliche Konflikte habe ich nicht getestet.

Code: Alles auswählen

@dirsonly 
Rename  TYPE=dirs FROM {filepath}\* TO "Test" WHENEXISTS=rename 
Copy MOVE {filepath}\Test\*.* TO {filepath}\
Delete FILE="{filepath}\Test" NORECYCLE SKIPNOTEMPTY QUIET
Benutzeravatar
tbone
Supporter
Beiträge: 698
Registriert: 29. Okt 2021 00:45

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von tbone »

Falls das Plastik-Gehirn noch nicht so richtig geschnackelt hat, einfach nochmal nachlegen.. o) Also, das ist wirklich verrückt, eine Powershell-Version und eine Version als Directory-Opus-Button Code als JScript und auch noch Installations-Anleitung, alles binnen Sekunden.

Bitte selber Testen, alles auf eigene Gefahr. Mein Hinweis sollte vorwiegend deutlich machen, wie man sich heute leicht selbst behelfen kann. Das ist der "AI-Mode" von Google, den findet jeder auf der Google-Seite, oder einfach direkt die Frage ins Suchfeld eingeben..
image.png
image.png (34.73 KiB) 9173770 mal betrachtet

Code: Alles auswählen

# Set the target root folder path
$rootPath = "C:\Your\Target\Folder"

# Get all subfolders that do not contain any other subfolders (leaf/last folders)
$lastFolders = Get-ChildItem -Path $rootPath -Recurse -Directory | Where-Object {
    (Get-ChildItem -Path $_.FullName -Directory).Count -eq 0
}

# Move files from those last folders exactly one level up
foreach ($folder in $lastFolders) {
    $files = Get-ChildItem -Path $folder.FullName -File
    $destinationDir = $folder.Parent.FullName

    foreach ($file in $files) {
        $destinationPath = Join-Path $destinationDir $file.Name

        # Move the file safely if a file with the same name doesn't exist
        if (-not (Test-Path $destinationPath)) {
            Move-Item -Path $file.FullName -Destination $destinationDir -Force
        } else {
            Write-Warning "Skipped (File already exists): $($file.FullName)"
        }
    }
}
image.png
image.png (23.83 KiB) 9173770 mal betrachtet

Code: Alles auswählen

@evalalways:
function OnClick(clickData) {
    var DOpus = clickData.func.sourcetab.DOpus;
    var cmd = clickData.func.command;
    cmd.deselect = false; // Keep selection for safety

    // Loop through selected items in the active tab
    for (var eSel = new Enumerator(clickData.func.sourcetab.selected_dirs); !eSel.atEnd(); eSel.moveNext()) {
        var currentDir = eSel.item();
        
        // Read folder content to check for subfolders
        var folderEnum = DOpus.FSUtil.ReadDir(currentDir.Path);
        var hasSubfolders = false;
        
        while (!folderEnum.complete) {
            var item = folderEnum.Next();
            if (item && item.is_dir) {
                hasSubfolders = true;
                break;
            }
        }
        
        // If it's a leaf folder (no subfolders), move its files up
        if (!hasSubfolders) {
            var filesInFolder = DOpus.FSUtil.ReadDir(currentDir);
            while (!filesInFolder.complete) {
                var fileItem = filesInFolder.Next();
                if (fileItem && !fileItem.is_dir) {
                    // Target path is the parent folder
                    var parentPath = currentDir.Path;
                    
                    // Clear existing instructions and queue the move command safely (without overwriting)
                    cmd.Clear();
                    cmd.AddFile(fileItem);
                    cmd.RunCommand("Copy MOVE TO=\"" + parentPath + "\" WHENEXISTS=rename");
                }
            }
        }
    }
}
image.png
image.png (13.16 KiB) 9173770 mal betrachtet

Code: Alles auswählen

Hier sind die deutschen Schritte, um den Code als Schaltfläche (Button) in Directory Opus einzufügen:
## Anleitung zur Einrichtung

   1. Rechtsklick auf eine leere Stelle in einer Ihrer Symbolleisten und wählen Sie Anpassen... (Customize...).
   2. Rechtsklick genau auf die Stelle der Symbolleiste, an der die neue Schaltfläche landen soll, und wählen Sie Neu > Neue Schaltfläche (New > New Button).
   3. Rechtsklick auf diese neu erstellte Schaltfläche und wählen Sie Bearbeiten... (Edit...).
   4. Ändern Sie oben im Editor-Fenster das Dropdown-Menü Funktion (Function) von Standard-Funktion (Opus Raw) auf Skript-Funktion (Script Function).
   5. Stellen Sie sicher, dass das Dropdown-Feld Skript-Typ (Script Type) direkt daneben auf JScript steht.
   6. Kopieren Sie den Code aus der vorherigen Antwort und fügen Sie ihn in das große Textfeld ein.
   7. Klicken Sie auf OK im Editor-Fenster und danach auf OK im Hauptfenster "Anpassen", um alles zu speichern.

## Funktionsweise
Wählen Sie einfach die gewünschten Ordner aus und klicken Sie auf den Button. Das Skript prüft automatisch, ob es sich um den jeweils letzten Unterordner (Leaf Folder) handelt, und verschiebt die darin enthaltenen Dateien eine Ebene nach oben.
Falls Sie Anpassungen am Verhalten wünschen, lassen Sie es mich wissen:

* Soll der Button die leeren Ordner danach direkt löschen?
* Möchten Sie vor dem Verschieben eine Sicherheitsabfrage sehen?


Benutzeravatar
Kundal
Moderator
Beiträge: 168
Registriert: 24. Okt 2021 18:02

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von Kundal »

Das Powershell-Skript funktioniert, hinterlässt aber die leeren Unterordner. Das DOpus JScript wirft mir diese Fehlermeldung aus:

Code: Alles auswählen

22.05.2026 21:54  Fehler in Zeile 11, Position 9 (RAW-Linie 12)
22.05.2026 21:54  Die Eigenschaft "FSUtil" eines undefinierten oder Nullverweises kann nicht abgerufen werden. (0x800a138f)
Benutzeravatar
Kundal
Moderator
Beiträge: 168
Registriert: 24. Okt 2021 18:02

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von Kundal »

@tbone: Puh, das ist echt gewöhnungsbedürftig mit der Plastikbirne. In deinem Beispiel ist z.B. die erste Zeile "var DOpus = clickData.func.sourcetab.DOpus;" kompletter Schwachsinn. Ich habe dann mal selbst Duck.ai bemüht und ähnlichen Blödsinn erhalten. Da wird dann aus "DOpus.FSUtil.ReadDir" mal eben frei erfundenes "DOpus.FSUtil.FolderRead" oder dieser lächerliche Versuch einen DOpus RunCommand auszuführen:

Code: Alles auswählen

// Move files and folders from sub to parent using Copy FILEMOVE
                var moveCmd = DOpus.Create.Command();
                moveCmd.SetSource("file", sub + "\\*");
                moveCmd.SetDestination(parentPath);
                moveCmd.RunCommand("Copy FILEMOVE");
Eigentlich würde ich ja sagen, wenn man keine Ahnung hat, einfach mal Fresse halten statt lustig drauflos Fakecode zu erfinden, aber die Grundstruktur des Scripts war (nach mehreren Anpassungen meiner Frage) trotzdem hilfreich, um daraus mit meinen beschränkten JScript-Kenntnissen ein funktionierendes Script zu basteln. Plastikbirne funktioniert halt doch nur mit Unterstützung einer funktionierenden Kohlenstoff-Einheit.

Das Ergebnis verschiebt den kompletten Inhalt (also auch evtl. vorhandene Ordner) von direkten Unterordnern der im Quellpfad ausgewählten Ordner in die darüber liegenden (= die ausgewählten) Ordner und löscht danach die leeren Unterordner.

Code: Alles auswählen

function OnClick(clickData)
{
    var cmd = clickData.func.command;
    var sels = clickData.func.sourcetab.selected;
    if (sels.count == 0) {
        DOpus.Output("Bitte mindestens einen Ordner auswählen.");
        return;
    }

    // For each selected item that is a folder, move contents of its direct subfolders up
    for (var i = 0; i < sels.count; i++) {
        var item = sels(i);
        if (!item.is_dir) continue;
        var parentPath = item.realpath;
        // enumerate direct subfolders
        var subEnum = DOpus.FSUtil.ReadDir(item);
        var subfolders = [];
        while (!subEnum.complete) {
            var e = subEnum.Next();
            if (!e) break;
            if (e.is_dir) subfolders.push(e.realpath);
        }

        // move contents of each subfolder into parentPath
        for (var j = 0; j < subfolders.length; j++) {
            var sub = subfolders[j];
            // move files
            try {
                // Move files and folders from sub to parent using Copy MOVE
                cmd.RunCommand("Copy MOVE \"" + sub + "\\*\" TO \"" + parentPath + "\"");
            } catch (ex) {
                DOpus.Output("Fehler beim Verschieben aus: " + sub + " -> " + parentPath + " : " + ex);
            }

            // try to remove the subfolder if empty
            try {
                cmd.RunCommand("Delete FILE=\"" + sub + "\" NORECYCLE SKIPNOTEMPTY QUIET");
            } catch (ex2) {
                // ignore
            }
        }
    }

    DOpus.Output("Verschieben abgeschlossen.");
}
Benutzeravatar
tbone
Supporter
Beiträge: 698
Registriert: 29. Okt 2021 00:45

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von tbone »

Also das Powershell-Ding funktioniert dann glaube ich so, wie Viper das haben wollte.

Was die JScript-Variante angeht:
Ja, die Plastikbirne hat vermutlich zu wenig Beispiele im Netz für DOpus-JScript, es patzt dann.. o) Danke für Deine Korrektur.. o)
Die von DIr gefixte JScript-Version macht dann aber noch nicht ganz das, was Viper haben wollte, oder? Er kann ja nicht "Unterordner1" und "Unterordner2" usw. selektieren, wenn die in unterschiedlichen Pfaden stecken. Also das Selektieren ginge zwar theoretisch mit FlatView / Find-Collection, ist aber zerrig.

Viper, Du musst jetzt mal sagen, ob Dir das was nützt, oder ob Du weitere Hilfe brauchst. Ich würde erstmal das Powershell-Ding versuchen, wenn ich Dich richtig verstanden habe. Du musst dort dann Deinen Pfad "D:\Bilder" in das Script eintragen, aber bitte erst auf einer gleichartigen Test-Struktur ausprobieren und je nachdem wieviele Files Du da umherzuschieben hast, vorher vll auch ein Backup machen.
Viper73
Beiträge: 16
Registriert: 10. Mär 2024 09:33

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von Viper73 »

Hallo zusammen,

erst vielen Dank an alle die hier so fleißig mitgemacht haben!
Ich musste erstmal googlen wie ich dann ein Powershell Script ausführe, hab damit schon lang nix mehr gemacht bzw. dort bisher immer nur ab und zu mal Befehle eingetippt ohne Script :lol:

Ich habe jetzt die Powershell Version von tbone verwendet (und zuerst in einer VMWare getestet), die klappt super. Danach einfach nach leeren Verzeichnissen gesucht und diese gelöscht. Jetzt hab ich es so wie ich es haben wollte. Das Script heb ich mir auf, brauch ich bestimmt ab und zu mal.

Also hat super geklappt, vielen Dank! Das hat mir echt wahnsinnig viel Arbeit erspart.
Viele Grüße!
Benutzeravatar
tbone
Supporter
Beiträge: 698
Registriert: 29. Okt 2021 00:45

Re: Dateien per Script/Funktion in übergeordneten Ordner verschieben?

Beitrag von tbone »

Wunderbar, danke für die Rückmeldung!.. o)
Antworten