【问题标题】:How can I move specific files from multiple subfolders to their respective parent folder? (Windows batch)如何将特定文件从多个子文件夹移动到各自的父文件夹? (Windows 批处理)
【发布时间】:2017-05-29 07:55:06
【问题描述】:

我有以下文件和文件夹结构(使用真实姓名):

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

我的问题是我需要从 StackXXX 文件夹中获取一个特定文件 PM*.* 到它们各自的 /dor 父文件夹中。然后可以删除 StackXXX 文件夹。

有数百个文件夹名称。理想情况下,我想要一个可以从 Carabidae 文件夹运行的批处理文件。

这需要一个批处理文件,因为会不断添加新的文件夹名称。

经过大量搜索,我从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)

它移动文件并删除文件夹,就像我想要的那样。但问题是它仅在从 FolderName 文件夹运行时才有效,这违背了脚本的省时目的。我不知道如何修改它以递归到子文件夹,所以我可以从顶层文件夹运行它。

非常感谢您的帮助!

【问题讨论】:

  • for /r 可以帮助你...
  • 我也是这么认为的,但它不适用于那行代码。我尝试分别替换 for /f 和每一个,都没有工作...
  • 您了解for /r 的工作原理吗?更多信息和使用方法请查看ss64.com/nt/for_r.html
  • 你必须使用标准的Windows路径分隔符\ 而不是/,这是开关指示器!否则,可能会发生意外行为...
  • 当你修改你正在枚举的目录树时,不要不要使用for /R,否则你可能会收到错误;原因见this threadfor /Fdir /B [/S] 一起确保在任何项目被修改之前枚举目录(树)...

标签: windows batch-file cmd windows-7


【解决方案1】:
@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\ 在路径中。如果是这样,请移动文件并删除目录。

if exist 门可确保目标目录包含多个 pm*.* 文件时不会出现问题。

所需的 MOVE 命令仅用于测试目的ECHOed。 验证命令正确后,将ECHO(MOVE 更改为MOVE 以实际移动文件。附加>nul 以禁止报告消息(例如1 file moved

所需的 RD 命令仅用于测试目的ECHOed。 验证命令正确后,将ECHO(RD更改为RD以实际删除目录。

move 命令末尾添加>nul 以根据需要禁止移动报告。

像往常一样,我建议您先对具有代表性的子树进行测试。

【讨论】:

  • 抱歉回复晚了,还没来得及测试就完成了。它运行良好,并且足够灵活,可以解决文件夹名称中的任何不一致问题。非常感谢!
【解决方案2】:

这是一个可能的解决方案,因为只有路径示例中的 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*目录!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    相关资源
    最近更新 更多