我试图重命名.jpg文件,这些文件位于e:\ study \ pubpmc \ test \ extracted的许多子目录之一。
我想将文件重命名为LastFolderName_ImageName.jpg。 (例如,如果Figure1.jpg位于e:\ study \ pubpmc \ test \ extracted \ folder1中 我希望它像这样重命名:folder1_Figure1.jpg)
所以我需要从文件的路径中取出最后一个文件夹名称。 因为这是我第一次使用批处理脚本,所以我很难过。
我用Google搜索并制作了类似的代码 但它似乎没有成功。
你能帮帮我,告诉我哪里做错了吗? 谢谢! :)
@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
)
答案 0 :(得分:2)
JosefZ解释了代码中明显的问题,但是他没有指出一个微妙的问题,尽管他的代码修复了它:
FOR / R(以及简单的FOR)在完成扫描磁盘驱动器之前立即开始迭代。循环可以重复已经命名的文件!这将导致它重命名两次,给出错误的结果。解决方案是使用带有'DIR / B'命令的FOR / F,因为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"
答案 1 :(得分:1)
:label
内使用:: label-like comment
和(command block in parentheses)
。在括号内使用其中任何一个 - 包括FOR
和IF
命令 - will break their context。(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
资源:
答案 2 :(得分:0)
如果你的程序或com文件在重命名时遍历这些文件夹,那么它应该能够获得当前的工作目录(path),pwd。您可以通过创建PREVIOUS_FOLDER并进行字符串替换来切除除LAST_FOLDER之外的所有内容。
或者您可以将'\'标记处的文件夹名称从pwd拆分为数组,并使用-1数组引用来获取最后一个文件夹名称。
在任何情况下,您都需要检查当前的工作目录命令。
如果您创建所有这些的大型文本列表并发出一次调用批处理文件。
那么你可能会更喜欢以下的东西: (Symmantic代码警告) (copy)/folderbase/some_folder/oneormore1/image_from_oneormore1.jpg(to)/folderbase/some_folder/oneormore1/oneormore1_image_from_oneormore1.jpg
而不是复制,窗口使用重命名,linux使用mv。
后一个例子只需要创建一个重复的列表,并在解析标记时用_替换\。
您提供的代码难以理解,因此很难辨别您是否可以简单地连接当前文件夹和图像名称(stringify),然后将它们写入或重命名。
答案 3 :(得分:0)
我已经为此编写了一个函数。你给它任何路径,它只返回它的文件名或路径名。适用于任何路径:Url,Windows路径,Linux路径等...
在批处理脚本的末尾复制此功能:(以下说明)
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 ===========================================================================
用法:
CALL :Name_Of_Path e:\study\pubpmc\test\extracted\folder1
ECHO %_Name_From_Path%
结果:folder1