我有一个批处理脚本:
@echo off
setlocal enableDelayedExpansion
SET /P UserInput=Please Enter a Number:
SET /A number=UserInput
ECHO number=%number%
for %%i in (*.jpeg) do call :JPG %%~ni %%i
goto :end
:JPG
set str=%1
set /a str2=%str:_color=%
set /a newnamej=%str2%+%number%
echo %1 ==> I can see the problem with it
set lastnamej=%newnamej%_color.jpeg
ren %2 %lastnamej%
goto :eof
:end
此脚本的目标是将所有文件放在一个文件夹中。它们都以数字(1_color.jpeg,2_color.jpeg,3_color.jpeg,..)命名,我想用一个额外的数字重命名它们(如果用户输入为5,则1_color.jpeg将变为6_color.jpeg,并且等等)。 我有这个脚本的问题。 如果我使用诸如555之类的数字,则第一个文件将在for循环中传递2次。
(小例子:1_color.jpeg和2_color.jpeg,
我使用我的脚本5,所以1_color.jpeg => 6_color.jpeg和2_color.jpeg => 7_color.jpeg然后,6_color.jpeg将再次被读取,并将变为11_color.jpeg,所以我的结果将是11_color.jpeg和7_color.jpeg)。
有人知道如何解决这个问题吗?
谢谢大家!
答案 0 :(得分:1)
用户Aacini在his answer中提供了一个很好的解决方案,指出了两个问题,即for
未提前完全枚举目录的事实(请参阅此主题:{ {3}})以及关于处理文件的排序顺序的逻辑缺陷。
但是,仍然存在一个问题,即dir /B /O:-N *.jpeg
的纯(反向)字母排序顺序,它仍然可能导致冲突,如下例所示:
9_color.jpeg 8_color.jpeg 7_color.jpeg 6_color.jpeg 5_color.jpeg 4_color.jpeg 3_color.jpeg 2_color.jpeg 10_color.jpeg 1_color.jpeg
因此,如果输入的数字为1
,则会尝试将文件9_color.jpeg
重命名为10_color.jpeg
,因为该文件尚未处理(因此已重命名),因此该文件已失败到11_color.jpeg
)。
要解决此问题,您需要以反向字母数字顺序正确排序项目。这可以通过在排序之前对数字进行左零填充来实现,因为这样,字母和字母数字排序顺序匹配。这是一个可能的实现:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_LOCATION=." & rem // (directory containing the files to rename)
set "_PATTERN=*_*.jpeg" & rem // (search pattern for the files to rename)
set "_REGEX1=^[0-9][0-9]*_[^_].*\.jpeg$" & rem // (`findstr` filter expression)
set "_TEMPFILE=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (path to temporary file)
rem // Retrieve numeric user input:
set "NUMBER="
set /P NUMBER="Please Enter a number: "
set /A "NUMBER+=0"
if %NUMBER% GTR 0 (set "ORDER=/R") else if %NUMBER% LSS 0 (set "ORDER=") else exit /B
rem /* Write `|`-separated list of left-zero-padded file prefixes, original and new
rem file names into temporary file: */
> "%_TEMPFILE%" (
for /F "tokens=1* delims=_" %%E in ('
dir /B "%_LOCATION%\%_PATTERN%" ^| findstr /I /R /C:"%_REGEX1%"
') do (
set "NAME=%%F"
setlocal EnableDelayedExpansion
set "PADDED=0000000000%%E"
set /A "NUMBER+=%%E"
echo !PADDED:~-10!^|%%E_!NAME!^|!NUMBER!_!NAME!
endlocal
)
)
rem /* Read `|`-separated list from temporary file, sort it by the left-zero-padded
rem prefixes, extract original and new file names and perform actual renaming: */
< "%_TEMPFILE%" (
for /F "tokens=2* delims=|" %%K in ('sort %ORDER%') do (
ECHO ren "%%K" "%%L"
)
)
rem // Clean up temporary file:
del "%_TEMPFILE%"
endlocal
exit /B
成功验证脚本的正确输出后,不要忘记删除ECHO
命令行前面的大写ren
命令。
该脚本使用一个临时文件,该文件接收一个|
- 分隔的表,第一个是填充数字前缀,第二个是原始文件名,第三列是新文件名,如下所示: / p>
0000000010|10_color.jpeg|11_color.jpeg 0000000001|1_color.jpeg|2_color.jpeg 0000000002|2_color.jpeg|3_color.jpeg 0000000003|3_color.jpeg|4_color.jpeg 0000000004|4_color.jpeg|5_color.jpeg 0000000005|5_color.jpeg|6_color.jpeg 0000000006|6_color.jpeg|7_color.jpeg 0000000007|7_color.jpeg|8_color.jpeg 0000000008|8_color.jpeg|9_color.jpeg 0000000009|9_color.jpeg|10_color.jpeg
临时文件由sort
命令读取和排序。提取第二列和第三列中的字符串并将其传递给ren
命令。