Windows批处理文件:从路径获取最后一个文件夹名称

时间:2015-03-29 09:35:26

标签: batch-file

我试图重命名.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


)

4 个答案:

答案 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)

  1. 避免在:label内使用:: label-like comment(command block in parentheses)。在括号内使用其中任何一个 - 包括FORIF命令 - will break their context
  2. (command block in parentheses)中使用变量。阅读EnableDelayedExpansion:延迟扩展将导致变量在执行时间扩展,而不是在解析时 [并且CLI一次解析所有(command block in parentheses) ]
  3. 下一个脚本应该适合您。注意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