如何在 FOR 循环内的 Windows 命令提示符中获取当前目录名称?

如何在 FOR 循环内的 Windows 命令提示符中获取当前目录名称?

我正在使用 Win-10 64 位。

鉴于我的 Windows 机器上的以下目录结构...

c:\tmp\Logs_UAT\
'-> folder1
|   '-> test.txt
'-> folder2
    '-> test.txt

...我尝试通过在目录名称前加上前缀来重命名每个目录中的所有文件,如下所示:

c:\tmp\Logs_UAT\
'-> folder1
|   '-> folder1_test.txt
'-> folder2
    '-> folder2_test.txt

为了实现这一点,我%basedir%使用 FOR 递归循环遍历文件,并在每个目录中使用内部 FOR“循环”获取当前目录名称,然后进行重命名。但是,当前目录通常无法正确导出。以下是允许重现此问题的 .bat 文件:

@echo off

set basedir=c:\tmp\Logs_UAT

for /R %basedir% %%I in (*) DO (
cd %%~pI

for %%G in (.) do echo %%~nxG> temp.temp
set /P curdir=<temp.temp
del /f temp.temp

echo.
echo -------------------
echo %%I
dir
echo %curdir%
echo -------------------
)

%curdir%它为两个文件输出相同的值:

C:\tmp>test.bat

-------------------
c:\tmp\Logs_UAT\folder1\test.txt
 Datenträger in Laufwerk C: ist OSDisk
 Volumeseriennummer: D280-2DC0

 Verzeichnis von C:\tmp\Logs_UAT\folder1

06.05.2020  19:29    <DIR>          .
06.05.2020  19:29    <DIR>          ..
06.05.2020  19:02                 0 test.txt
               1 Datei(en),              0 Bytes
               2 Verzeichnis(se), 291.684.151.296 Bytes frei
folder2
-------------------
.
-------------------
c:\tmp\Logs_UAT\folder2\test.txt
 Datenträger in Laufwerk C: ist OSDisk
 Volumeseriennummer: D280-2DC0

 Verzeichnis von C:\tmp\Logs_UAT\folder2

06.05.2020  19:29    <DIR>          .
06.05.2020  19:29    <DIR>          ..
06.05.2020  19:02                 0 test.txt
               1 Datei(en),              0 Bytes
               2 Verzeichnis(se), 291.684.151.296 Bytes frei
folder2
-------------------

C:\tmp\Logs_UAT\folder2>

我试过:

  1. 新鲜的控制台窗口
  2. 控制台和批处理文件
  3. 有时我会得到第一个文件夹名称,有时我会得到第二个
  4. 在网上搜索了很多

我宁愿坚持使用标准的 Windows 实用程序,因为我必须将脚本分发给可能没有额外软件的其他用户。

如何在 FOR 循环内的 Windows 命令提示符中获取当前目录名称?

答案1

确实,DelayedExpansion 有所帮助,感谢 DavidPostill。以下是工作脚本:

@echo off
SETLOCAL EnableDelayedExpansion
set basedir=c:\tmp\Logs_UAT

for /R %basedir% %%I in (*) DO (
cd %%~pI

for %%G in (.) do echo %%~nxG> temp.temp
set /P curdir=<temp.temp
del /f temp.temp

echo !curdir!
)

endlocal

答案2

  • 为了让您在一次循环中获得与问题相同的结果:
@echo off

set "_=echo\ -------------------"
for /D /R "c:\tmp\Logs_UAT" %%I in (*
)do %_% & echo\%%~nxI & dir "%%~nxI" & echo\ %%~nxI & %_%
  • 你的输出:
 -------------------

 Volume in drive C has no label.
 Volume Serial Number is 32E8-70C5

 Directory of c:\tmp\Logs_UAT\folder1

05/06/2020  02:40 PM    <DIR>          .
05/06/2020  02:40 PM    <DIR>          ..
05/06/2020  02:41 PM                 8 test.txt
               1 File(s)              8 bytes
               2 Dir(s)   3,128,999,936 bytes free
 folder1
 -------------------
 -------------------

 Volume in drive C has no label.
 Volume Serial Number is 32E8-70C5

 Directory of c:\tmp\Logs_UAT\folder2

05/06/2020  02:47 PM    <DIR>          .
05/06/2020  02:47 PM    <DIR>          ..
05/06/2020  02:48 PM                 7 folder2.txt
               1 File(s)              7 bytes
               2 Dir(s)   3,128,999,936 bytes free
 folder2
 -------------------


  1. 您不需要使用多个for循环,for /D /R只需在所有子目录中使用一个循环递归即可,这样就DelayedExpansion没有必要

  2. 为什么需要使用任何附加循环temp.temp在整个目录中创建和删除文件?当您已经在循环中将当前文件夹的名称(在所有子目录中递归)存储在变量中(并且还有许多其他可用的变量)时,因此,要在循环中使用,只需使用它们即可……for /Dfor/R/D%%~nxI

    • Use the FOR variable syntax replacement:
      %~pI        - expands %I to a path only
      %~nI        - expands %I to a file name only
      %~xI        - expands %I to a file extension only
    • The modifiers can be combined to get compound results:
      %~pnI       - expands %I to a path and file name only
      %~pnxI      - expands %I to a path, file name and extension only
    • )do %_% & echo\%%~nxI & dir "%%~nxI" & echo\ %%~nxI & %_%

      观察.: 关于使用%%~xdirectory名称观察注释中ss64.com

    • Full Stop Bug
      Although Win32 will not recognise any file or directory name that begins or ends 
      with a '.' (period/full stop) it is possible to include a Full Stop in the middle
      of a directory name and this can cause issues with FOR /D.
    • Parameter expansion will treat a Full Stop as a file extension, so for a directory
      name like "Sample 2.6.4" the output of %%~nI will be truncated to "Sample 2.6" to
      return the whole folder name use %%I or %%~nxI
  3. 您不需要使用DelayedExpansion,您可以使用cmd /v/c echo\!curdir!echo\%%~nxI

  4. 为了获得与代码输出问题相同的输出,您可以为横幅设置/使用一个变量(set _=echo\ ----),并将其调整为所需的布局输出:

    • )do %_% & echo\%%~nxI & dir "%%~nxI" & echo\ %%~nxI & %_%

    或者,按照一种常规格式

    • @echo off
      
      set "_=echo\ -------------------"
      
      for /D /R "c:\tmp\Logs_UAT" %%I in (*)do (
      
      %_%
      echo\%%~nxI
      dir "%%~nxI"
      echo\ %%~nxI
      %_%
      
      )
  5. 对于一行中带有for /D /R循环的一个简单而简短的输出选项,您可以尝试:

    • @echo off
      
      for /d /r "c:\tmp\Logs_UAT" %%I in (*)do set "curdir=%%~nxI" && cmd /v /c " echo\!curdir!"

答案3

我查找各级目录的一般解决方案是:

@ECHO OFF
setlocal enabledelayedexpansion EnableExtensions

::Sample BAT to find all levels directories
:: FULL current path: "G:\First our directory\Second our directory\Third. - Strange . directory\Fourth and last  directory"

:: Get full current path (could be passed as a parameter to use as subroutine)
SET ActualP=%CD%
:: Set starting counter number
SET /A Countdir=0
:: Find number of directorie levels, echoes them to console and set associated variables
FOR %%G in ("%ActualP:\=" "%") DO (SET /A "CountDir+=1"
  set "Lvl=%%G"
  set "Lvl!Countdir!=!Lvl!"
  ECHO Lvl!Countdir!:!Lvl!
  )
ECHO.
:: Check number of levels to console
ECHO Levels of directorie: %CountDir%
ECHO.
:: Get last (current) level of directory free of double quotes and echoes it to console 
:: between brackets to assure not extra chars are present
SET "LastLvl=%Lvl:"=%"
ECHO LastLvl: [%LastLvl%]
:: Just to be sure that the variables have been set:
ECHO.
ECHO Third level of directorie: %Lvl3%
PAUSE
EXIT

:: This wiil echoes to console:
::   
::   Lvl1:"G:"
::   Lvl2:"First our directory"
::   Lvl3:"Second our directory"
::   Lvl4:"Third. - Strange . directory"
::   Lvl5:"Fourth and last  directory"
::   
::   Levels of directorie: 5
::   
::   LastLvl: [Fourth and last  directory]
::   
::   Third level of directorie: "Second our directory"
::   Premere un tasto per continuare . . .

相关内容