Batch file 文件中循环的批处理

Batch file 文件中循环的批处理,batch-file,for-loop,Batch File,For Loop,我有一个批处理脚本: @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 newnam

我有一个批处理脚本:

@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 so 1_color.jpeg=>6_color.jpeg和2_color.jpeg=>7_color.jpeg一起使用,但随后,6_color.jpeg将被再次读取,并将变为11_color.jpeg,因此我的结果将是11_color.jpeg和7_color.jpeg)。
有人知道如何解决这个问题吗


谢谢大家

问题有两部分:(*.jpeg)中%%i的
命令可能会受到重命名文件在整个文件列表中所占位置的影响,因此某些文件可能会重命名两次,在某些特定情况下,如果文件较多,则最多会重命名三次

解决方案是使用
for/F%%i in('dir/B*.jpeg')…
命令,该命令首先获取所有文件的列表,然后启动重命名过程

此外,重命名必须从最后一个文件到第一个文件,以避免重复编号

但是,在这种情况下,将
for/F
的“tokens=1*delims=”选项结合使用也允许以更简单的方式处理文件名中以下划线分隔的第一个数字:

@echo off
setlocal EnableDelayedExpansion

SET /P number=Please Enter a Number:
ECHO number=%number%

for /F "tokens=1* delims=_" %%a in ('dir /O:-N /B *.jpeg') do (
   set /A newNum=%%a+number
   ren "%%a_%%b" "!newNum!_%%b"
)
用户在中提供了一个很好的解决方案,指出了当前存在的两个问题,即
for
没有提前完全枚举目录(请参阅此线程:)以及与处理文件的排序顺序有关的逻辑中的缺陷

但是,
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关闭
setlocal EnableExtensions DisableDelayedExpansion
rem//在此处定义常量:
设置“_LOCATION=。”&rem/(包含要重命名的文件的目录)
设置“\u PATTERN=*.\u*.jpeg”&rem//(搜索要重命名的文件的模式)
设置“_REGEX1=^[0-9][0-9]*.\\.jpeg$”&rem/(`findstr`过滤器表达式)
设置“\u TEMPFILE=%TEMP%\%~n0\u%RANDOM%.tmp”&rem/(临时文件的路径)
rem//检索数字用户输入:
设置“数字=”
set/P NUMBER=“请输入一个数字:”
设置/A“数字+=0”
如果%NUMBER%GTR 0(设置“订单=/R”),如果%NUMBER%LSS 0(设置“订单=”)否则退出/B
rem/*Write`|`—左零填充文件前缀的分隔列表,原始和新前缀
将rem文件名转换为临时文件:*/
>“%\u临时文件%”(
对于/F“tokens=1*delims=“%%E in('
目录/B“%\u位置%\%\u模式%”^ findstr/I/R/C:“%\u REGEX1%”
""做"(
设置“名称=%%F”
setlocal EnableDelayedExpansion
设置“填充=0000000000%%E”
设置/A“数字+=%%E”
回声!填充:~-10!^ |%%E|!名称!^ |!编号!|!名称!
端部
)
)
rem/*读取临时文件中的`|`-分隔列表,按左零填充的顺序进行排序
rem前缀,提取原始和新文件名,并执行实际重命名:*/
<“%\u临时文件%”(
对于/F“tokens=2*delims=|”%%K in('sort%ORDER%')do(
ECHO ren“%%K”“%%L”
)
)
rem//清理临时文件:
删除“%\u临时文件%”
端部
退出/B
成功验证脚本的正确输出后,不要忘记删除
ren
命令行前面的大写字母
ECHO
command

该脚本使用一个临时文件,该文件接收一个以
|
分隔的表格,表格的第一列为填充数字前缀,第二列为原始文件名,第三列为新文件名,如下所示:

00000000 10|10|u color.jpeg | 11|u color.jpeg
000000000 1|1|u color.jpeg | 2|u color.jpeg
000000000 2| 2|u color.jpeg | 3|u color.jpeg
000000000 3|3|u color.jpeg | 4|u color.jpeg
000000000 4|4|u color.jpeg | 5|u color.jpeg
000000000 5|5|u color.jpeg | 6|u color.jpeg
000000000 6|6|u color.jpeg | 7|u color.jpeg
000000000 7|7|u color.jpeg | 8|u color.jpeg
000000000 8|8|u color.jpeg | 9|u color.jpeg
000000000 9|9|u color.jpeg | 10|u color.jpeg

通过
sort
命令读取和排序临时文件。第二列和第三列中的字符串被提取并传递给
ren
命令。

我使用外部文件解决了问题。首先,我将所有文件复制到一个.txt文件中,然后逐行复制红色文件,最后,删除它。重命名或删除正常
for
循环中的文件不是一个好主意,因为
for
不会提前枚举所有文件--请参阅此问题:由于
dir/O:-N
的纯逆字母排序顺序,可能仍然会发生冲突,因为顺序不是
10
9
,。。。,
2
1
,但
9
,…,
2
10
1
,因此,如果输入的数字是
1
,则尝试将
9
重命名为
10
,该数字已经存在+1无论如何,因为您解决了原始代码的两个问题…感谢您的回复!我所做的似乎更容易理解。但是