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

问题描述 投票:0回答:4

我正在尝试重命名 .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


)
batch-file
4个回答
3
投票

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"



2
投票
避免在
    :label
  1. 内使用
    :: label-like comment
    (command block in parentheses)
    。在括号内使用它们中的任何一个 - 包括
    FOR
    IF
    命令 -
    都会破坏它们的上下文
  2. (command block in parentheses)
  3. 内使用变量。阅读
    EnableDelayedExpansion
    :延迟扩展将导致变量在执行时而不是在解析时扩展[并且CLI立即解析所有(command block in parentheses)]
    
    
    
  4. 下一个脚本应该适合你。注意
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

0
投票

在任何情况下,您都需要检查当前的工作目录命令。

如果您创建所有这些的大型文本列表并对批处理文件发出单个调用。

那么你可能会得到更好的结果: (符号代码警告) (复制)/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 路径等...


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.