关于Windows批处理文件:是否有办法列出某个目录及其子目录中的所有文件(或所有特定类型),包括相对于列表中当前(或搜索)目录的路径?
例如,如果我想要当前目录和子目录中的所有.txt文件及其完整路径,我可以
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
有可能吗?
如果我的帖子太混乱了:我基本上想要 List files recursively in Linux CLI with path relative to the current directory ,但仅限于Windows。
答案 0 :(得分:34)
迭代目录树并列出相关文件路径的最简单(但不是最快)的方法是使用FORFILES。
forfiles /s /m *.txt /c "cmd /c echo @relpath"
相对路径将以
中的前导.\
引用
".\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
答案 1 :(得分:22)
您只需获取当前目录的字符长度,然后将其从绝对列表中删除
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
)
答案 2 :(得分:9)
对于包含等号(=
)的根路径,此答案无效。 (感谢@dbenham指出这一点。)
已编辑:修复了包含!
的路径问题,@ dbenham再次发现(谢谢!)。
除了计算长度和提取子字符串之外,您还可以使用不同的方法:
存储根路径;
清除文件路径的根路径。
这是我的尝试(对我有用):
@ECHO OFF
SETLOCAL DisableDelayedExpansion
SET "r=%__CD__%"
FOR /R . %%F IN (*) DO (
SET "p=%%F"
SETLOCAL EnableDelayedExpansion
ECHO(!p:%r%=!
ENDLOCAL
)
r
变量与当前目录一起分配。 除非当前目录是磁盘驱动器的根目录,否则它不会以 (不再是这种情况,因为脚本现在读取\
结束,我们通过附加字符进行修改。__CD__
变量,其值始终以\
结尾(感谢@jeb!),而不是CD
。)
在循环中,我们将当前文件路径存储到变量中。然后我们输出变量,沿途剥离根路径。
答案 3 :(得分:5)
当然,您可以在Batch中编写一个递归算法,它可以精确控制您在每个嵌套子目录中执行的操作:
@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
答案 4 :(得分:3)
@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
)