2017-05-29 5 views
1

Ich habe die folgende Datei- und Ordnerstruktur (echte Namen verwenden):Wie kann ich bestimmte Dateien aus mehreren Unterordnern in ihren jeweiligen übergeordneten Ordner verschieben? (Windows Batch)

Carabidae/Pterostichinae/FolderNameXXX/dor/StackXXX/files.tif 

Mein Problem ist, dass ich eine bestimmte Datei erhalten muß, PM * *, von den StackXXX Ordnern in sie. jeweilige/dor übergeordnete Ordner. Der StackXXX-Ordner kann dann gelöscht werden.

Es gibt Hunderte von Ordnernamen. Idealerweise möchte ich eine Batch-Datei, die ich aus dem Carabidae-Ordner ausführen kann.

Dies muss eine Batch-Datei sein, da ständig neue FolderNames hinzugefügt werden.

Nach vieler Suche fand ich eine halb-Arbeitslösung von this StackOverflow answer:

for /f "delims==" %%i in ('dir /a:d /b') do for /f "delims==" %%f in ('dir %%i /a:d /b') do (move "%%i\%%f\PM*.*" "%%i"&&rd "%%i\%%f" /s /q) 

es die Datei verschiebt und löscht den Ordner, wie ich will. Das Problem ist jedoch, dass es nur funktioniert, wenn es aus einem FolderName-Ordner ausgeführt wird, was den zeitsparenden Zweck des Skripts zunichtemacht. Ich weiß nicht, wie ich es ändern kann, um in Unterordner zu gelangen, damit ich es aus dem obersten Ordner ausführen kann.

Vielen Dank für jede Hilfe! Hier

+0

'for/r' kann Ihnen helfen ... – SteveFest

+0

Ich dachte es auch, aber es hat nicht mit dieser Codezeile funktioniert. Ich habe versucht, sowohl 'for/f 'und jeder einzeln zu ersetzen, hat keine der Zeiten funktioniert ... – trilobutt

+0

Verstehst du, wie' for/r funktioniert? Bitte überprüfen Sie https://ss64.com/nt/for_r.html für weitere Informationen und Methoden der Verwendung – SteveFest

Antwort

1

ist eine mögliche Lösung, da nur die XXX Teile in Ihrem Pfad Probe sind variabel:

rem // Enumerate `FolderName*` directories: 
for /D %%R in ("Carabidae\Pterostichinae\FolderName*") do (
    rem // Enumerate `Stack*` sub-directories within `dor` sub-directories: 
    for /F "delims= eol=|" %%D in ('dir /B /A:D "%%~R\dor\Stack*"') do (
     rem // Check for `PM*.*` files in `Stack*` sub-directories: 
     (
      rem // Enumerate `PM*.*` files: 
      for /F "delims= eol=|" %%F in ('dir /B /A:-D "%%~R\dor\%%D\PM*.*"') do (
       rem /* Move `PM*.*` file one directory level up, overwriting 
       rem an already existing file, if applicable: */ 
       ECHO move /Y "%%~R\dor\%%D\%%F" "%%~R\dor\%%F" 
      ) 
     ) && (
      rem /* Remove `Stack*` sub-directory after file movement; 
      rem this is skipped if no `PM*.*` files have been found in the `Stack*` 
      rem sub-directory, so when the `for /F %%F` loop did never iterate: */ 
      ECHO rd /S /Q "%%~R\dor\%%D" 
     ) 
    ) 
) 

Nachdem erfolgreich getestet, ob die richtigen Elemente zurückgegeben werden, entfernen die Groß- Fall ECHO Befehle, um tatsächlich PM*.* Dateien zu verschieben und Stack* Verzeichnisse zu entfernen!

2
@ECHO OFF 
SETLOCAL 
SET "sourcedir=u:\Carabidae" 
FOR /f "tokens=1*delims=" %%a IN (
'dir /b /s /a-d "%sourcedir%\pm*.*" ' 
) DO IF EXIST "%%a" (
FOR %%p IN ("%%~dpa..\.") DO IF /i "%%~nxp"=="dor" (
    ECHO %%a|FINDSTR /i "\\dor\\Stack" >NUL 
    IF NOT ERRORLEVEL 1 (
    ECHO MOVE /y "%%~dpa\pm*.*" "%%~dpa..\" 
    ECHO RD /s /q "%%~dpa" 
) 
) 
) 

GOTO :EOF 

Sie müssten die Einstellung von sourcedir zu ändern, um Ihre Umstände anzupassen.

alle der pm*.* Dateien finden, Dateinamen %%a

Sicherstellen, dass das übergeordnete Verzeichnis dor ist und sicherstellen, dass \dor\stack\ im Weg ist. Wenn ja, verschieben Sie die Datei (en) und entfernen Sie das Verzeichnis.

Das if exist Gate stellt keine Probleme dar, wenn ein Zielverzeichnis mehr als eine Datei enthält.

Die erforderlichen MOVE-Befehle sind lediglich ECHO für Testzwecke. Nachdem Sie überprüft haben, dass die Befehle korrekt sind, ändern Sie ECHO(MOVE in MOVE, um die Dateien tatsächlich zu verschieben. Append >nul zum Unterdrücken von Meldungsnachrichten (z. B. 1 file moved)

Die erforderlichen RD-Befehle sind lediglich ECHO für Testzwecke. Nachdem Sie sichergestellt haben, dass die Befehle korrekt sind, ändern Sie ECHO(RD zu RD, um die Verzeichnisse tatsächlich zu löschen.

Fügen Sie >nul am Ende des Befehls move hinzu, um den move-report bei Bedarf zu unterdrücken.

Wie üblich, würde ich vorschlagen, dass Sie zuerst gegen einen repräsentativen Teilbaum testen.

+0

Entschuldigung für die späte Antwort, fertige Arbeit, bevor ich es vollständig testen konnte. Es funktionierte perfekt und ist flexibel genug, um Inkonsistenzen in Ordnernamen zu berücksichtigen. Vielen Dank! – trilobutt

Verwandte Themen