目前我有一个 100 行的 CSV 文件。每行第一列文件夹名称后面有 10 个图像名称。
FolderName1,ImageName1,ImageName2,ImageName3,...,ImageName10
FolderName2,ImageName1,ImageName2,ImageName3,...,ImageName10
... and so on upto
FolderName100,ImageName1,ImageName2,ImageName3,...,ImageName10
我还有 100 个文件夹,每个文件夹有 10 张图像。我需要根据 CSV 中图像所在的目录对图像进行批量重命名。 这就是我到目前为止所尝试的, 读取 CSV 文件,
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for /f "tokens=1-10 delims=," %%a in (CSVExample.csv) do (
echo %%a
echo %%b
echo %%c
echo %%d
echo %%e
echo %%f
echo %%g
echo %%h
echo %%i
echo %%j
echo %%k
)
pause
但是,上面的代码并没有读取第10个图像名称(ImageName10)。我不明白为什么?..
而且,这就是我正在尝试重命名部分的方法,
OldImageName1 to ImageName1
OldImageName2 to ImageName2
OldImageName3 to ImageName3
OldImageName4 to ImageName4
OldImageName5 to ImageName5
OldImageName6 to ImageName6
...等等。
旧图像名称不必符合任何条件。我只需要重命名图像,无论其现有的名称字符串如何。
可以使用以下批处理文件来完成此任务:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
if not exist "%~dp0CSVExample.csv" echo ERROR: Missing file: "%~dp0CSVExample.csv"& exit /B 1
for /F "usebackq tokens=1* delims=," %%G in ("%~dp0CSVExample.csv") do if exist "%%~G\" (
for /F "delims=?" %%I in ('set ? 2^>nul') do set "?%%I?="
for %%I in ("%%~G\*") do set "?%%~nxI?=1"
for %%I in (%%H) do (
set "FileRenamed="
for /F "delims=?" %%J in ('set ? 2^>nul') do if not defined FileRenamed (
ren "%%~G\%%J" "%%~I"
if not errorlevel 1 (
set "?%%J?="
set "FileRenamed=1"
)
)
)
)
endlocal
批处理文件不使用延迟变量扩展来处理包含感叹号的文件夹路径和文件名。
批处理文件目录中的 CSV 文件中的每一行首先使用逗号作为分隔符分成两个子字符串。第一个值(文件夹名称)根据
ASCII表分配给指定的循环变量
G
,并用逗号分隔的所有文件名分配给下一个循环变量 H
。
注意: 因此,文件夹名称和文件名称都不能包含逗号。包含空格或这些字符
&()[]{}^=;!'+`~
之一的文件夹或文件名必须用 CSV 文件中的 "
括起来,否则处理将无法正确进行。
首先检查当前分配给循环变量
G
的文件夹是否存在。如果使用绝对路径或相对于当前目录的路径指定的文件夹不存在,则忽略 CSV 文件中的当前行。
接下来执行一个
for /F
循环,删除所有以问号开头和结尾的环境变量。
然后运行标准的
for
循环,按照文件系统返回的顺序获取当前文件夹中所有非隐藏文件的名称,定义一个文件名以?
开头、以结尾的环境变量?
与值 1
无关紧要。问号用作变量名的开头和结尾,因为文件名不能包含问号。这样内存中终于有了一个以?
开头和结尾的环境变量列表,它们是当前文件夹中的文件名。
第三个
for
循环现在处理 CSV 文件当前行中的逗号分隔文件名。
对于每个文件名,首先未定义环境变量
FileRenamed
。
接下来,像之前一样,由 ?
启动的命令进程在后台以
for /F
作为参数执行命令 SET,以输出名称以问号开头的所有环境变量。因此,输出是之前为当前文件夹确定的文件名列表,并且该列表由
for /F
循环捕获和处理。
仅当尚未对从 CSV 文件中的行读取的当前文件名进行重命名时,才会处理从以问号开头和结尾的环境变量名称中提取文件名的捕获行。
当前文件夹中的下一个文件将重命名为 CSV 文件当前行中的当前文件名。如果文件重命名成功,则重命名的文件的名称将从环境变量列表中删除,并且环境变量
FileRenamed
被定义为跳过最初在当前文件夹中找到的文件的所有其他文件名。
此过程可能导致文件夹中的文件数与 CSV 文件中的行中的文件数不匹配。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。
call /?
... 解释 %~dp0
... 参数 0 的驱动器和路径,批处理文件路径始终以反斜杠结尾。echo /?
endlocal /?
exit /?
for /?
if /?
ren /?
set /?
setlocal /?
阅读有关 使用命令重定向运算符的 Microsoft 文档,了解
2>nul
的说明。重定向运算符 >
必须在 FOR命令行上使用脱字符号
^
进行转义,以便在 Windows 命令解释器在执行命令 FOR(执行嵌入的 set
命令)之前处理这些命令行时将其解释为文字字符与使用在后台启动的单独命令进程一致。
我相信这可以解决您的问题。相关方法论评论包含在
rem
备注中。
@ECHO Off
SETLOCAL
rem The following settings for the source directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files\t w o"
SET "filename1=%sourcedir%\q72507524.txt"
FOR /f "usebackqtokens=1*delims=," %%b IN ("%filename1%") DO (
rem %%b contains the directoryname, %%c a comma-separated list of the new filenames for that subdirectory
FOR /f "delims=" %%e IN ('dir /b /a-d "%sourcedir%\%%b"') DO (
rem %%e contains each filename (only) in the directory
FOR %%y IN (%%c) DO IF NOT EXIST "%sourcedir%\%%b\%%y" IF EXIST "%sourcedir%\%%b\%%e" REN "%sourcedir%\%%b\%%e" "%%y"
)
)
GOTO :EOF
在应用于真实数据之前,请务必根据测试目录进行验证。