batch file:使用相对path列出目录中的所有文件

关于Windowsbatch file:是否有办法列出某个目录及其子目录中的所有文件(或全部特定types),包括相对于列表中当前(或search)目录的path?

例如,如果我想要所有的txt文件在当前目录和子目录中的完整path,我可以

for /r . %%g in (*.txt) do echo %%g >> C:\temp\test.txt 

要么

 dir *.txt /b /s >> C:\temp\test.txt 

我会得到类似的东西

 C:\test\Doc1.txt C:\test\subdir\Doc2.txt C:\test\subdir\Doc3.txt 

如果我做

 for /r . %%g in (*.txt) do echo %%~nxg >> C:\temp\test.txt 

我会得到类似的东西

 Doc1.txt Doc2.txt Doc3.txt 

但是我真正想要的是:

 Doc1.txt subdir\Doc2.txt subdir\Doc3.txt 

可能吗?

如果我的post太混乱了:我基本上希望“ 在Linux CLI中用相对于当前目录的pathrecursion列出文件 ”,仅用于Windows。

您可以简单地获取当前目录的字符长度,并将其从绝对列表中删除

 setlocal EnableDelayedExpansion for /L %%n in (1 1 500) do if "!__cd__:~%%n,1!" neq "" set /a "len=%%n+1" setlocal DisableDelayedExpansion for /r . %%g in (*.log) do ( set "absPath=%%g" setlocal EnableDelayedExpansion set "relPath=!absPath:~%len%!" echo(!relPath! endlocal ) 

迭代目录树并列出相关文件path的最简单(但不是最快)的方法是使用FORFILES 。

 forfiles /s /m *.txt /c "cmd /c echo @relpath" 

相对path将被引用一个领先的.\

 ".\Doc1.txt" ".\subdir\Doc2.txt" ".\subdir\Doc3.txt" 

删除引号:

 for /f %%A in ('forfiles /s /m *.txt /c "cmd /c echo @relpath"') do echo %%~A 

删除引号和前导.\

 setlocal disableDelayedExpansion for /f "delims=" %%A in ('forfiles /s /m *.txt /c "cmd /c echo @relpath"') do ( set "file=%%~A" setlocal enableDelayedExpansion echo !file:~2! endlocal ) 

或者不使用延迟扩展

 for /f "tokens=1* delims=\" %%A in ( 'forfiles /s /m *.txt /c "cmd /c echo @relpath"' ) do for %%F in (^"%%B) do echo %%~F 

这个答案将无法正确使用包含等号( = )的根path。 (感谢@dbenham指出了。)


编辑:修复了包含path的问题! ,再次被@dbenham发现(谢谢!)。

除了计算长度和提取子string,您可以使用不同的方法:

  • 存储根path;

  • 清除文件path的根path。

这是我的尝试(为我工作):

 @ECHO OFF SETLOCAL DisableDelayedExpansion SET "r=%__CD__%" FOR /R . %%F IN (*) DO ( SET "p=%%F" SETLOCAL EnableDelayedExpansion ECHO(!p:%r%=! ENDLOCAL ) 

rvariables分配给当前目录。 除非当前目录是磁盘驱动器的根目录,否则不会以\结尾,我们通过附加字符来修改。 (不再是这种情况,因为脚本现在读取__CD__variables,其值始终以\ (谢谢@jeb!)结尾,而不是CD 。)

在循环中,我们将当前文件path存储到variables中。 然后我们输出variables,一路剥离根path。

当然,你可以在Batch中写一个recursionalgorithm,让你精确控制你在每个嵌套的子目录中做什么:

 @echo off set mypath= call :treeProcess goto :eof :treeProcess setlocal for %%f in (*.txt) do echo %mypath%%%f for /D %%d in (*) do ( set mypath=%mypath%%%d\ cd %%d call :treeProcess cd .. ) endlocal exit /b 
 @echo on>out.txt @echo off setlocal enabledelayedexpansion set "parentfolder=%CD%" for /r . %%g in (*.*) do ( set "var=%%g" set var=!var:%parentfolder%=! echo !var! >> out.txt )