2017-05-29 3 views
1

J'ai la structure du fichier et le dossier suivant (en utilisant les vrais noms):Comment puis-je déplacer des fichiers spécifiques de plusieurs sous-dossiers vers leur dossier parent respectif? (Batch Windows)

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

Mon problème est que je dois obtenir un fichier spécifique, PM * *, à partir des dossiers StackXXX dans leur. dossiers parent/dor respectifs. Le dossier StackXXX peut ensuite être supprimé.

Il existe des centaines de noms de dossiers. Idéalement, je voudrais un fichier batch que je peux exécuter à partir du dossier Carabidae.

Il doit s'agir d'un fichier de traitement par lots car de nouveaux noms de dossiers seront ajoutés en permanence.

Après beaucoup de recherches, je trouve une solution semi-travail de 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) 

Il déplace le fichier et supprime le dossier, tout comme je veux. Mais le problème est que cela ne fonctionne que lorsqu'il est exécuté à partir d'un dossier FolderName, ce qui annule le but de gagner du temps du script. Je ne sais pas comment le modifier pour recurse dans les sous-dossiers afin que je puisse l'exécuter à partir du dossier supérieur.

Merci beaucoup pour toute aide!

+0

'pour/r' peut vous aider ... – SteveFest

+0

Je le pensais aussi, mais cela ne fonctionnait pas avec cette ligne de code. J'ai essayé de remplacer à la fois 'for/f' et chacun séparément, n'a pas fonctionné de tous les temps ... – trilobutt

+0

Comprenez-vous comment' for/r' fonctionne? Veuillez vérifier https://ss64.com/nt/for_r.html pour plus d'informations et les méthodes d'utilisation – SteveFest

Répondre

1

Voici une solution possible, étant donné que seuls les XXX parties dans votre échantillon de chemin sont variables:

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" 
     ) 
    ) 
) 

Après avoir testé avec succès ou non les éléments corrects sont renvoyés, retirer le palier supérieur cas ECHO commandes pour réellement déplacer PM*.* fichiers et supprimer Stack* répertoires!

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 

Vous devez modifier le paramètre sourcedir en fonction des circonstances.

Trouver tous les pm*.* fichiers, les noms de fichiers %%a

Vérifiez que le répertoire parent est dor et veiller à ce que \dor\stack\ est dans le chemin. Si c'est le cas, déplacez le (s) fichier (s) et supprimez le répertoire.

La porte if exist n'assure aucun hiccough si un répertoire cible contient plus d'un fichier pm*.*.

Les commandes MOVE requises sont simplement ECHO éditées à des fins de test. Après avoir vérifié que les commandes sont correctes, remplacez ECHO(MOVE par MOVE pour déplacer réellement les fichiers. Ajoutez >nul pour supprimer les messages de rapport (par exemple 1 file moved)

Les commandes RD requises sont simplement ECHO éditées à des fins de test. Une fois que vous avez vérifié que les commandes sont correctes, remplacez ECHO(RD par RD pour supprimer réellement les répertoires.

Ajoutez >nul à la fin de la commande move pour supprimer le rapport de mouvement si nécessaire.

Comme d'habitude, je vous suggère de tester d'abord contre un sous-arbre représentatif.

+0

Désolé pour la réponse tardive, fini le travail avant que je puisse le tester pleinement. Cela a fonctionné parfaitement et est assez flexible pour tenir compte des incohérences dans les noms de dossiers. Merci beaucoup! – trilobutt