Estoy reorganizando datos existentes y necesito crear un nuevo subdirectorio para recibir todos los archivos y directorios existentes. El objetivo de esto es dejar espacio para una nueva línea de productos y, al mismo tiempo, mejorar la convención de nomenclatura de los datos existentes.
Por ejemplo, datos que actualmente se ven así:
\root directory\
+-proj1357
+-closing binder
+-refi
+-compliance
+-proj2468
+-disbursements
+-compliance
+-proj3579
+-pre-close
+-compliance
En realidad debería verse así:
\root directory\
+-proj1357
+-dpl
+-closing binder
+-refi
+-compliance
+-proj2468
+-dpl
+-disbursements
+-compliance
+-proj3579
+-dpl
+-pre-close
+-compliance
El problema que tengo es que parece que no puedo obtener el comando correcto sin quedarme atrapado en un bucle recursivo. Mientras pirateaban esto juntos, con frecuencia me encontré con el error "no se puede realizar una copia cíclica".
La buena noticia es que tengo una solución que funciona, pero requiere tres comandos separados y una sintaxis personalizada para cada directorio del proyecto.
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\
Por lo que puedo decir, el comando 1 mueve todos los archivos y directorios al nuevo subdirectorio. También causa un problema recursivo al mover archivos en el directorio de nivel de proyecto a un subdirectorio más profundo. Así que confío en el Comando 2 para recuperar archivos que alguna vez estuvieron en el directorio a nivel de proyecto. Luego, el Comando 3 elimina el subdirectorio más profundo.
¿Existe una mejor manera de ejecutar un comando o un archivo por lotes a través de un sistema basado en Windows? Lo ideal sería rastrear todos los directorios a nivel de proyecto y mover el contenido al nuevo subdirectorio. Estoy pensando en procesar más de mil proyectos, por lo que creo que vale la pena descubrir cómo realizar el bucle correctamente.
Para obtener un contexto más visual de a lo que me enfrento, vea la captura de pantalla a continuación.
ACTUALIZADO
Después de intentar hacerlo funcionar usando el método de línea de comando de tres pasos descrito anteriormente, cedí y adapté la respuesta de jiggunjer para que se adaptara a mi entorno. A continuación se muestra el archivo por lotes de MS que utilicé. También agregué comentarios para aclarar el propósito de cada línea.
@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"
)
)
)
Respuesta1
En cada uno de esos 8 directorios raíz ejecute este comando:
FOR /D %p IN ("*") DO robocopy /E /MOVE "%p" "%p/DPL"
Versión de Powershell 3.0+:
gci -dir -name | foreach-object{robocopy /E /MOVE $_ ($_ + '\DPL')}
O
Según su captura de pantalla, una solución todo en uno sería algo como:
@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"
)
¡Feliz re-paternidad!
Respuesta2
Puedes hacerlo:
@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"
)
Toma 2 parámetros. La primera es la ruta que contiene sus proyectos, la segunda es la ruta temporal.
Lo que hace es simplemente mover el proyecto a una ruta temporal y luego volver a moverlo al nombre del proyecto anterior/dpl.
Nota: se supone que la primera ruta contiene solo directorios del proyecto e ignorará los directorios que no sean de este nivel.