5

Я реорганизую существующие данные, и мне нужно создать новый подкаталог, чтобы получать все существующие файлы и каталоги. Цель этого состоит в том, чтобы освободить место для новой линейки продуктов, одновременно улучшая соглашение об именовании существующих данных.

Например, данные, которые в настоящее время выглядят примерно так:

\root directory\
+-proj1357
  +-closing binder
  +-refi
  +-compliance
+-proj2468
  +-disbursements
  +-compliance
+-proj3579
  +-pre-close
  +-compliance

На самом деле должно выглядеть так:

\root directory\
+-proj1357
  +-dpl
    +-closing binder
    +-refi
    +-compliance
+-proj2468
  +-dpl
    +-disbursements
    +-compliance
+-proj3579
  +-dpl
    +-pre-close
    +-compliance

У меня проблема в том, что я не могу получить правильную команду без застревания в рекурсивном цикле. Во время взлома этого я часто сталкивался с ошибкой "не могу выполнить циклическое копирование".

Хорошая новость заключается в том, что у меня есть работающее решение, но оно требует трех отдельных команд и настраиваемого синтаксиса для каждого каталога проекта.

command 1> ROBOCOPY G:\proj1357 DPL /E /MOVE
command 2> MOVE G:\proj1357\DPL\DPL\*.* G:\proj1357\DPL
command 3> RMDIR G:\proj1357\DPL\DPL\

Насколько я могу судить, команда 1 перемещает все файлы и каталоги в новый подкаталог. Это также вызывает рекурсивную проблему, перемещая файлы из каталога уровня проекта в более глубокий подкаталог. Поэтому я полагаюсь на Command 2 для восстановления файлов, которые когда-то были в каталоге уровня проекта. Затем команда 3 удаляет более глубокий подкаталог.

Есть ли лучший способ запустить командный или командный файл через систему на базе Windows? В идеале он должен сканировать все каталоги уровня проекта и перемещать содержимое в новый подкаталог. Я смотрю на обработку более тысячи проектов, так что я думаю, что стоит потратить время на выяснение того, как правильно его зациклить.

Для более наглядного контекста того, с чем я столкнулся, см. Скриншот ниже. скриншот каталога Windows


ОБНОВЛЕНО

Попытавшись заставить его работать, используя трехшаговый метод командной строки, описанный выше, я сдался и адаптировал ответ jiggunjer's, чтобы соответствовать моей среде. Ниже приведен пакетный файл MS, который я использовал. Я также добавил замечания, чтобы уточнить назначение каждой строки.

@echo off
rem run this batch file in top level directory
rem top level directory should contain all project number directories
rem assumes that all directories starting with a digit are project number directories 

rem initialize the listing of all directories
set rootlist=dir /b /a:D

rem initialize numerical filtering
set filter=findstr "^[1-9]"

rem loop through all directories that comply with filtering (start with a digit)
rem use command extension /F to process (in this case) command output
rem identifies all project number parent-directories
rem assign parent-directories to variable %%P, as in 'Project'
FOR /F %%P in ('%rootlist% ^| %filter%') DO (
    rem pass the variable %%P to the moveproject loop
    call :moveproject "%%P"

    rem move files that were ignored by the robocopy command
    rem these are 'loose' files that were in the project number directory, but not saved in any subdirectory
    rem assumes the robocopy command successfully creates the DPL directory
    MOVE %%P\*.* %%P\DPL\
)

rem pause to review command log
pause

:moveproject
rem ensure that the parameter has value
rem converts variable %%P to parameter no. 1
if not [%1] == [] (

rem loop through all sub-directories under each project number
rem use command extension /D to process directories only
rem removing any surrounding quotes (") from parameter no. 1 by using optional syntax -- percent-tilde
rem assign sub-directories to variable %%O, as in 'Origin'
FOR /D %%O IN ("%~1\*") DO (
    rem display values
    echo project number %%P
    echo directory origin %%O

    rem delimit origin directory using backslash character
    rem use command extension /F to process (in this case) strings
    rem assign the second delimited piece to variable %%D, as in 'Destination'
    rem effectively drops all text to the left of the first backslash character
    FOR /F "tokens=2 delims=\" %%D IN ("%%O") DO (
        rem display values
        echo %%D
        echo directory destination %%P\DPL\%%D

        rem move all directories to DPL sub-directory
        rem simultaniously creates the receiving DPL directory
        robocopy /E /MOVE "%%O" "%%P\DPL\%%D"
        )
    )
)

2 ответа2

0

Вы можете сделать это:

@echo off
mkdir %2
cd %1
SETLOCAL EnableDelayedExpansion
for /f "delims=" %%D in ('dir /a:d /b') do (
    set project_path=%%~fD
    move "!project_path!" "%~2%\temp"
    mkdir "!project_path!"
    move "%~2%\temp" "!project_path!\dpl"
)

Принимает 2 параметра. Первый путь, который содержит ваши проекты, второй временный путь.

Он просто перемещает проект во временный путь, а затем возвращает его к старому имени проекта / dpl.

Примечание: предполагается, что первый путь содержит только каталоги проекта, и на этом уровне будут игнорироваться не-каталоги.

0

В каждом из этих 8 корневых каталогов выполните эту команду:

FOR /D %p IN ("*") DO robocopy /E /MOVE "%p" "%p/DPL"

Версия Powershell 3.0+:

gci -dir -name | foreach-object{robocopy /E /MOVE $_ ($_ + '\DPL')}

ИЛИ ЖЕ

На основе вашего скриншота решение «все в одном» будет выглядеть примерно так:

@echo off
REM Assume: Running in top level dir. 
REM Assume: Only project parent fodlers start with a digit.
set rootlist=dir /b /a:D
set filter=findstr "^[1-9]"
FOR /f %%d in ('%rootlist% ^| %filter%') DO (
call :moveproject "%%d"
)

:moveproject
if not [%1] == [] (
FOR /D %%p IN ("%~1\*") DO robocopy /E /MOVE "%%p" "%%p/DPL"
)

Счастливого перевоспитания!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .