修改批处理脚本循环中的变量

时间:2015-12-09 15:44:47

标签: batch-file

我正在根据文件名将文件移动到预设文件夹。我不想制作新文件夹。因此,只有在相应文件夹已存在的情况下才能移动文件。

文件名都遵循相同的模式:1234_123456_AA_***********.doc / pdf

我在下面有以下脚本:

@echo on
for /r %%f in (*.*) do (
    echo processing "%%f"
    for /f "tokens=1-3 delims=_" %%a in ("%%~nxf") do (
        move "%%f" C:\Users\xxxxxxxxx\Desktop\MOVEFILES\%%a_%%b_%%c\
    )
)
pause

但我遇到的问题是某些文件名在循环变量%%b中有一个'0'占位符,例如1234_0123456_AA。但是这个文件名应该被解释为1234_123456_AA,我想把这个文件移到相应的文件夹中。

我写了这个:

@echo on
SETLOCAL ENABLEDELAYEDEXPANSION
for /r %%f in (*.*) do (
    for /f "tokens=1-3 delims=_" %%a in ("%%~nxf") do (
        set z=%%b%
        echo !z:~-6!
        move "%%f" C:\Users\xxxxxxxxx\Desktop\MOVEFILES\%%a_%%z_%%c\
    )
)
pause

我得到 echo 以删除'0'占位符,但需要在文件应该移动到的文件路径中将其返回到%%b

在代码中修改什么以获得所需的行为?

1 个答案:

答案 0 :(得分:0)

使用以下代码并应用JosefZ的更正并进行一些其他改进:

@echo off
setlocal EnableDelayedExpansion
for /R %%F in (*_*_*.*) do (
    for /F "tokens=1-3 delims=_" %%A in ("%%~nxF") do (
        set "MiddlePart=%%B"
        set "MiddlePart=!MiddlePart:~-6!"
        if exist "%USERPROFILE%\Desktop\MOVEFILES\%%A_!MiddlePart!_%%C\*" (
            move /Y "%%F" "%USERPROFILE%\Desktop\MOVEFILES\%%A_!MiddlePart!_%%C"
        )
    )
)
endlocal
pause

下面详细解释代码的改进。

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • echo /?
  • endlocal /?
  • if /?
  • move /?
  • set /?
  • setlocal /?

1。搜索模式

第一个改进是第一个 FOR 中使用的模式,因为只有文件名中应至少移动2个下划线。这种模式仍然不是最好的模式,但足以完成这项任务。

2。循环变量

最好以大写形式使用循环变量,以避免修饰符出现问题。

例如使用as循环变量%%f并在循环%%~f内使用循环变量f的字符串(不能是文件或文件夹名称)而不包含引号,命令处理器退出批处理并显示错误消息,因为它需要多一个字母,循环变量%%~f被解释为循环变量?的文件/文件夹的全名。

循环变量和修饰符区分大小写。因此,%%~F由命令处理器解释为循环变量F的字符串,不包含引号,%%~fF作为文件/文件夹名称,包含循环变量{{的文件/文件夹的完整路径和扩展名1}}。

其他一些字符如F也可以用作循环变量。

3。使用引号

为环境变量赋值

在将字符串分配给环境变量时,最好使用

#

使用此处显示的引号具有以下优点:命令处理器忽略最后双引号后不可见的空格/制表符。

但是只使用

set "variable=text or other variable"

在第一次等号注册到行终止之后的所有内容都被分配给变量,包括尾随空格和批处理文件中此行上可能错误添加的选项卡。这几乎从来都不是好的,并且是批量执行问题的常见来源,可以通过正确使用引号轻松避免。

使用如下所示的引号也不好,因为在这种情况下,两个双引号都是分配给变量的文本的一部分(加上尾随空格/制表符)。这有时很有用,但通常是编码错误。

set variable=text or other variable

4。延迟扩张

在使用set variable="text or other variable" ... (定义的块中引用变量集或修改,如果应使用当前变量值而不是分配给块上方变量的值,则需要延迟扩展。因此,在原始代码中使用)是错误的,因为变量%%z未在第一个 FOR 循环之上定义,因此在执行循环时始终没有替换。

5。环境变量USERPROFILE

在命令提示符窗口z中运行会导致显示当前用户帐户的所有预定义环境变量。有一个变量 USERNAME ,还有 USERPROFILE ,其中包含带有set文件夹和其他用户帐户相关文件夹的用户个人资料目录的路径。使用环境变量 USERPROFILE 可以减少批处理文件对Windows的Windows版本和语言的依赖。

<强>注意:

第一个 FOR 因为Desktop在当前目录及其所有子目录上递归而运行。当内部 FOR 循环将当前目录树中所有找到的文件移动到/R的子目录时,当前目录应该永远不应该是此路径的任何目录。