【问题标题】:Recursively append folder name to files in it and moves all files to base folder Windows batch file递归地将文件夹名称附加到其中的文件并将所有文件移动到基​​本文件夹 Windows 批处理文件
【发布时间】:2020-03-25 01:11:54
【问题描述】:

我想递归地将文件夹(和父文件夹)名称附加到该文件夹​​包含的每个 *.txt 文件。之后,我想将所有文件移动到基​​本文件夹并删除所有文件夹。我需要在 Windows BATCH 脚本中实现这一点。例如:

\BaseFolder\A01\B01\EX1.TXT
\BaseFolder\C01\EX2.TXT
\BaseFolder\EX3.TXT

收件人:

\BaseFolder\A01-B01-EX1.TXT
\BaseFolder\C01-EX2.TXT
\BaseFolder\EX3.TXT

感谢 JosefZ,我找到了这个解决方案:

Recursively append folder name to the files in Windows batch file

@echo OFF
SETLOCAL EnableExtensions
for /F "delims=" %%G in ('dir /B /S "C:\Source\*.txt"') do (
    for %%g in ("%%~dpG.") do rename "%%~fG" "%%~nxg_%%~nxG"
)
pause

FOR 循环在哪里:

  • 外部 %%G 循环创建 .txt 文件的静态列表(递归),并且
  • 内部 %%g 循环获取每个特定文件的父文件夹。

但这仅解决了我的部分目标。有人可以帮忙吗?

【问题讨论】:

  • 您链接的解决方案只能处理一个子目录级别,它不会移动任何文件,只是重命名它们......

标签: windows batch-file recursion cmd scripting


【解决方案1】:

这是一个“有趣”的想法:

@Set "BaseFolder=C:\Users\Mustafa\BaseFolder"
@ForFiles /P "%BaseFolder%" /S /M *.txt /C "Cmd /C If @IsDir==FALSE For /F 0x22Tokens=*Delims=.\0x22 %%# In (@RelPath)Do @If Not 0x22%%#0x22==@File Set 0x22_=%%#0x22&Call Move /Y 0x22%BaseFolder%\%%#0x22 0x22%BaseFolder%\%%_:\=-%%0x22>NUL"

请注意,这个未经测试的解决方案很可能有命令行长度限制。因此,如果您的初始基本文件夹在卷内很深和/或其树很深或带有长文件和目录名称,我会避免它。鉴于该警告信息,请记住根据需要调整第一行的完整路径值。

【讨论】:

  • 不错的一个!由于您已经使用call 来延迟扩展,您还可以在move 命令行中将%BaseFolder% 更改为%%BaseFolder%%,以便在那里也延迟扩展,从而减少forfiles 看到的整体命令行长度,这愚蠢地将其限制为仅 253 个字符。无论如何,请注意,您的方法不会像想要的那样清理空目录...
  • 注意到@aschipfl,我把清空关掉了,因为它可能会遇到字符长度问题,(感谢您确认这是数字)。它也应该是一个简单的,在后续行中删除“空”目录例程,无需太多努力。我本可以做出这样的努力,但由于 OP 没有对这项任务进行任何尝试,我认为无论如何简单的搜索都应该给他们。
【解决方案2】:

下面的脚本应该完成你想要的,即移动和重命名文件为预定义并删除剩余的空子目录(参见所有解释性rem 备注):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_ROOT=.\BaseFolder" & rem // (target base directory)
set "_MASK=*.txt"        & rem // (file search pattern)
set "_CHAR=-"            & rem // (separator character)

rem // Switch to target directory:
pushd "%_ROOT%" && (
    rem // Loop through list of relative paths of matching files:
    for /F "tokens=1* delims=:" %%E in ('
        xcopy /L /S /I "%_MASK%" "%TEMP%" ^| find ":"
    ') do (
        rem // Store current relative file path, initialise variables:
        set "FILE=%%F" & set "NAME=" & set /A "NUM=0"
        rem // Toggle delayed expansion to avoid trouble with `!` and `^`:
        setlocal EnableDelayedExpansion
        rem // Loop through all individual elements of file relative path:
        for %%I in ("!FILE:\=" "!") do (
            endlocal
            rem // Store current path element and count them:
            set "ITEM=%%~I" & set /A "NUM+=1"
            setlocal EnableDelayedExpansion
            rem // Build new file name and pass it over `endlocal` barrier:
            for /F "delims=" %%N in ("!NAME!%_CHAR%!ITEM!") do (
                endlocal
                set "NAME=%%N"
                setlocal EnableDelayedExpansion
            )
        )
        rem // Finalise new file name:
        if defined _CHAR set "NAME=!NAME:*%_CHAR%=!"
        rem // Actually move and rename the current file:
        > nul move "!FILE!" "!NAME!"
        rem // Switch to parent directory of current file:
        pushd "!FILE!\.." && (
            rem // Loop through parent directory elements:
            for /L %%N in (2,1,!NUM!) do (
                rem // Try to remove parent directory when empty, go one up:
                set "DD=!CD!" & cd ".." & 2> nul rd "!DD!"
            )
            rem // Return to previous working directory:
            popd
        )
        endlocal
     )
     rem // return to original working directory:
     popd
)

endlocal
exit /B

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多