1

我正在尝试创建我的第一个 DOS 脚本(更习惯于 bash)。

我正在尝试创建一个脚本,该脚本将使用序列号和年份作为前缀重命名我的照片。我创建了这个脚本:

@ECHO OFF
setlocal EnableDelayedExpansion

echo.
SET /P Year=Please enter Year (YYYY) : 
SET /P Start=Starting Number          : 

dir     

set /A i=%Start%
for %%f in (*.JPG) do call :renameit "%%f"
goto done

:renameit

echo %1 %i%
set str=%i%
set str=0000!str:.=!
set str=!str:~-4!  
ren %1 PICT_%Year%_%str%.JPG
set /A i+=1

:done

问题是它有时工作正常,有时会重新命名一个已经重命名的文件。这是 2 个示例(如您所见,我在上面的脚本中添加了 DIR 和 ECHO 用于故障排除):

运行 1(正确):

Directory of C:\TEST

07/01/2013  10:55    <DIR>          .
07/01/2013  10:55    <DIR>          ..
04/08/2011  14:28            16.823 PICT_2012_0005.JPG
04/08/2011  14:28            16.823 PICT_2012_0006.JPG
04/08/2011  14:28            16.823 PICT_2012_0007.JPG
07/01/2013  10:56               368 script.cmd
           4 File(s)         50.837 bytes
           2 Dir(s)  30.342.901.760 bytes free
"PICT_2012_0005.JPG" 5
"PICT_2012_0006.JPG" 6
"PICT_2012_0007.JPG" 7

运行 2(失败):

Directory of C:\TEST

07/01/2013  10:56    <DIR>          .
07/01/2013  10:56    <DIR>          ..
04/08/2011  14:28            16.823 PICT_2011_0005.JPG
04/08/2011  14:28            16.823 PICT_2011_0006.JPG
04/08/2011  14:28            16.823 PICT_2011_0007.JPG
07/01/2013  10:56               368 script.cmd
           4 File(s)         50.837 bytes
           2 Dir(s)  30.342.901.760 bytes free
"PICT_2011_0005.JPG" 5
"PICT_2011_0006.JPG" 6
"PICT_2011_0007.JPG" 7
"PICT_2012_0005.JPG" 8

知道我做错了什么吗?

谢谢

4

1 回答 1

3

将评论扩展为完整答案。

这是命令的已知功能/问题/未定义行为for。当遍历文件目录并对这些文件进行修改时,for 循环不会在文件夹中保留静态文件列表。相反,它只是检查下一个文件,直到文件系统没有返回任何内容。但是,当在循环中修改文件时,文件系统会将修改视为附加文件,并再次将其发送到 for 循环。这将导致重新处理未知数量的文件(基于 for 循环和文件系统的竞争条件)。

有关它的深入讨论,请参阅此论坛。

http://www.dostips.com/forum/viewtopic.php?f=3&t=4138&sid=463cb91964f497c478afcca79c33384a

您也可以使用此 for 语句:for /F "delims=" %%F in ('dir /B *.jpg') do call :renameit "%%~fF"

dir命令将在运行时生成目录中文件的静态列表,以防止文件递归。

于 2013-01-07T15:23:32.000 回答