我正在尝试重命名 .jpg 文件,该文件位于 e:\study\pubpmc est xtracted 的许多子目录之一中。
我想将文件重命名为 LastFolderName_ImageName.jpg。 (例如,如果Figure1.jpg 位于 e:\study\pubpmc est xtracted old1 我希望它像这样重命名:folder1_Figure1.jpg)
所以我需要从文件路径中取出最后一个文件夹名称。 由于这是我第一次使用批处理脚本,因此我遇到了困难。
我用谷歌搜索并制作了类似的代码 但似乎没有成功。
你能帮我解决一下并告诉我哪里做错了吗? 谢谢你! :)
@echo off
cd /D "e:\study\pubpmc\test\extracted"
for /r %%f in (*.jpg) do (
set mydir=%%~dpf
set mydir=%mydir:\=;%
for /f "tokens=* delims=;" %%i in (%mydir%) do call :LAST_FOLDER %%i
goto :EOF
:LAST_FOLDER
if "%1"=="" (
@echo %LAST%
goto :EOF
)
set LAST=%1
SHIFT
goto :LAST_FOLDER
)
JosefZ 解释了您的代码的明显问题,但他未能指出一个微妙的问题,尽管他的代码修复了它:
FOR /R(以及简单的 FOR)在完成扫描磁盘驱动器之前立即开始迭代。循环可以重复已经命名的文件!这会导致它被重命名两次,从而给出错误的结果。解决方案是将 FOR /F 与命令“DIR /B”结合使用,因为 FOR /F 始终在迭代之前完成命令。 JosefZ 还提供了适用于大多数情况的代码。但有一个更简单且始终有效的解决方案:
@echo off
for /f "delims=" %%A in (
'dir /b /s /a-d "e:\study\pubpmc\test\extracted\*.jpg"'
) do for %%B in ("%%A\..") do ren "%%A" "%%~nxB_%%~nxA"
"%%A\.."
将文件名视为文件夹并走到父文件夹。所以
%%~nxB
给出了父文件夹的名称。该命令可以作为一长串命令直接从命令行运行(无批处理):
for /f "delims=" %A in ('dir /b /s /a-d "e:\study\pubpmc\test\extracted\*.jpg"') do @for %B in ("%A\..") do @ren "%A" "%~nxB_%~nxA"
:label
:: label-like comment
和 (command block in parentheses)
。在括号内使用它们中的任何一个 - 包括 FOR
和 IF
命令 - 都会破坏它们的上下文。 在
(command block in parentheses)
EnableDelayedExpansion:延迟扩展将导致变量在执行时而不是在解析时扩展[并且CLI立即解析所有
(command block in parentheses)
]
rename
语句仅用于调试目的。
echo
资源:
@ECHO OFF >NUL
SETLOCAL enableextensions disabledelayedexpansion
set "fromFolder=e:\study\pubpmc\test\extracted"
rem my debug setting set "fromFolder=D:\path"
for /F "tokens=*" %%f in ('dir /B /S /A:D "%fromFolder%\*.*"') do (
set "mydir=%%~ff"
set "last=%%~nxf"
call :renameJPG
)
@ENDLOCAL
goto :eof
:renameJPG
rem echo "%mydir%" "%last%"
for /f "tokens=*" %%i in ('dir /B /A:-D "%mydir%\*.jpg" 2^>nul') do (
echo ren "%mydir%\%%~nxi" "%last%_%%~nxi"
)
goto :eof
SETLOCAL
、disableDelayedExpansion
等
Windows CMD 命令行的 A-Z 索引在任何情况下,您都需要检查当前的工作目录命令。
如果您创建所有这些的大型文本列表并对批处理文件发出单个调用。
那么你可能会得到更好的结果: (符号代码警告) (复制)/folderbase/some_folder/oneormore1/image_from_oneormore1.jpg (到)/folderbase/some_folder/oneormore1/oneormore1_image_from_oneormore1.jpg
window使用rename代替copy,linux使用mv。
后一个示例只需要创建一个重复列表并在解析标记时将 \ 替换为 _ 。
您给出的代码很难理解,因此很难辨别是否可以简单地连接当前文件夹和图像名称(字符串化),然后在它们所在的位置写入或重命名它们。
我已经为此编写了一个函数。你给它任何路径,它只返回你的文件名或路径名。适用于任何路径:Url、Windows 路径、Linux 路径等...
ENDLOCAL
用途:
rem ===========================================================================
:Name_From_Path
SetLocal
set _TMP_FOLDERNAME=%1
for %%g in ("%_TMP_FOLDERNAME%") do set _TMP_FOLDERNAME=%%~nxg
EndLocal & set _Name_From_Path=%_TMP_FOLDERNAME%
goto :EOF
rem ===========================================================================
结果:文件夹1