一种方法是在forfiles 中嵌套for %I 循环并使用%~I 扩展——在命令提示符窗口中使用此代码:
forfiles /P "C:\root" /M "*.txt" /C "cmd /Q /C for %I in (@relpath) do echo %~I"
要在批处理文件中使用该代码,您必须将 %-signs 加倍:
forfiles /P "C:\root" /M "*.txt" /C "cmd /Q /C for %%I in (@relpath) do echo %%~I"
返回的文件列表将是(依赖于原始问题中的示例文件):
.\file1.txt
.\file2.txt
另一种变体是将另一个forfiles 嵌套在初始字符串的主体中,因为forfiles 删除了给定字符串中的(非转义)双引号,例如/C 之后的命令行:
forfiles /P "C:\root" /M "*.txt" /C "cmd /C forfiles /P @path\.. /M @file /C \"cmd /C echo @relpath\""
或者(加倍的内部forfiles 是故意的,这可以解决一个错误——参见this post):
forfiles /P "C:\root" /M "*.txt" /C "forfiles forfiles /P @path\.. /M @file /C \"cmd /C echo @relpath\""
内部forfiles 将仅枚举一项,即外部循环传递的一项。由于@relpath在执行内部循环时已经展开,因此引号被删除,因为它们没有被转义。
所以返回的文件列表看起来像(再次从原始问题中获取示例文件):
.\file1.txt
.\file2.txt
行之间的额外换行符由forfiles 生成。您可以使用重定向来避免这种情况(关闭forfiles 输出,但在控制台窗口中仅显示echo 输出):
> nul forfiles /P "C:\root" /M "*.txt" /C "cmd /C forfiles /P @path\.. /M @file /C 0x22cmd /C > con echo @relpath0x22"