我正在重新组织现有数据,需要创建一个新的子目录来接收所有现有文件和目录。这样做的目的是为新的产品线腾出空间,同时改善现有数据的命名约定。
例如,当前数据如下所示:
\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 将所有文件和目录移动到新的子目录中。它还会通过将项目级目录中的文件移动到更深的子目录中而导致递归问题。因此我依靠命令 2 来恢复曾经位于项目级目录中的文件。然后命令 3 删除更深的子目录。
有没有更好的方法可以通过基于 Windows 的系统运行命令或批处理文件? 理想情况下,它会遍历所有项目级目录,并将内容移动到新的子目录。我正在考虑处理一千多个项目,所以我认为值得花时间弄清楚如何正确循环它。
更新
在尝试使用上面概述的三步命令行方法使其工作后,我放弃了并调整了 jiggunjer 的答案以适合我的环境。下面是我使用的 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"
)
)
)
答案1
在这 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"
)
祝您重新成为父母愉快!
答案2
你可以这样做:
@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。
注意:它假定第一个路径只包含项目目录,并且将忽略此级别的非目录。