如何将特定文件从多个子文件夹移动到它们各自的父文件夹? (Windows 批次)
How can I move specific files from multiple subfolders to their respective parent folder? (Windows batch)
我有以下文件和文件夹结构(使用真实姓名):
Carabidae/Pterostichinae/FolderNameXXX/dor/StackXXX/files.tif
我的问题是我需要将 StackXXX 文件夹中的一个特定文件 PM*.* 放入它们各自的 /dor 父文件夹中。然后可以删除 StackXXX 文件夹。
FolderName 有数百个。理想情况下,我想要一个可以从 Carabidae 文件夹中 运行 的批处理文件。
这需要是一个批处理文件,因为会不断添加新的文件夹名称。
经过大量搜索,我从 this Whosebug 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)
它移动文件并删除文件夹,正如我所愿。但问题是它仅在来自 FolderName 文件夹的 运行 时有效,这违背了脚本节省时间的目的。我不知道如何修改它以递归到子文件夹中,所以我可以从顶级文件夹 运行 它。
非常感谢您的帮助!
这是一个可能的解决方案,前提是您的路径示例中只有 XXX
部分是可变的:
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"
)
)
)
成功测试是否返回正确的项目后,删除大写 ECHO
命令 以实际移动 PM*.*
文件并删除Stack*
个目录!
@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
您需要更改 sourcedir
的设置以适合您的情况。
找到所有pm*.*
个文件,文件名改为%%a
确保父目录是 dor
并确保 \dor\stack\
在路径中。如果是这样,请移动文件并删除目录。
如果目标目录包含多个 pm*.*
文件,if exist
门可确保不会出现问题。
所需的 MOVE 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将ECHO(MOVE
更改为MOVE
以实际移动文件。附加 >nul
以禁止报告消息(例如 1 file moved
)
所需的 RD 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将ECHO(RD
更改为RD
以实际删除目录。
如果需要,在 move
命令末尾添加 >nul
以抑制移动报告。
像往常一样,我建议您先针对代表性子树进行测试。
我有以下文件和文件夹结构(使用真实姓名):
Carabidae/Pterostichinae/FolderNameXXX/dor/StackXXX/files.tif
我的问题是我需要将 StackXXX 文件夹中的一个特定文件 PM*.* 放入它们各自的 /dor 父文件夹中。然后可以删除 StackXXX 文件夹。
FolderName 有数百个。理想情况下,我想要一个可以从 Carabidae 文件夹中 运行 的批处理文件。
这需要是一个批处理文件,因为会不断添加新的文件夹名称。
经过大量搜索,我从 this Whosebug 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)
它移动文件并删除文件夹,正如我所愿。但问题是它仅在来自 FolderName 文件夹的 运行 时有效,这违背了脚本节省时间的目的。我不知道如何修改它以递归到子文件夹中,所以我可以从顶级文件夹 运行 它。
非常感谢您的帮助!
这是一个可能的解决方案,前提是您的路径示例中只有 XXX
部分是可变的:
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"
)
)
)
成功测试是否返回正确的项目后,删除大写 ECHO
命令 以实际移动 PM*.*
文件并删除Stack*
个目录!
@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
您需要更改 sourcedir
的设置以适合您的情况。
找到所有pm*.*
个文件,文件名改为%%a
确保父目录是 dor
并确保 \dor\stack\
在路径中。如果是这样,请移动文件并删除目录。
如果目标目录包含多个 pm*.*
文件,if exist
门可确保不会出现问题。
所需的 MOVE 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将ECHO(MOVE
更改为MOVE
以实际移动文件。附加 >nul
以禁止报告消息(例如 1 file moved
)
所需的 RD 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将ECHO(RD
更改为RD
以实际删除目录。
如果需要,在 move
命令末尾添加 >nul
以抑制移动报告。
像往常一样,我建议您先针对代表性子树进行测试。