批处理文件:列出目录中的所有文件以及相对路径
关于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
是否可能?
如果我的帖子太令人困惑:我基本上想要 在 Linux CLI 中以相对于当前目录的路径递归列出文件,但仅适用于 Windows。
Concerning Windows batch files: Is there a way to list all the files (or all of a specific type) in a certain directory and its subdirectories, including the paths relative to the current (or the search) directory in the list?
For example, if I want all the .txt files in the current directory and subdirectories with their full paths, I can do
for /r . %%g in (*.txt) do echo %%g >> C:\temp\test.txt
or
dir *.txt /b /s >> C:\temp\test.txt
and I will get something like
C:\test\Doc1.txt
C:\test\subdir\Doc2.txt
C:\test\subdir\Doc3.txt
If I do
for /r . %%g in (*.txt) do echo %%~nxg >> C:\temp\test.txt
I will get something like
Doc1.txt
Doc2.txt
Doc3.txt
But what I really want is:
Doc1.txt
subdir\Doc2.txt
subdir\Doc3.txt
Is it possible?
If my post is too confusing: I basically want List files recursively in Linux CLI with path relative to the current directory, but just for Windows.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
迭代目录树并列出相对文件路径的最简单(但不是最快)的方法是使用 FORFILES。
相对路径将用前导
.\
引用,如删除引号:
删除引号和前导
.\
:或不使用延迟扩张
The simplest (but not the fastest) way to iterate a directory tree and list relative file paths is to use FORFILES.
The relative paths will be quoted with a leading
.\
as inTo remove quotes:
To remove quotes and the leading
.\
:or without using delayed expansion
您可以简单地获取当前目录的字符长度,并将它们从您的绝对列表中删除
You could simply get the character length of the current directory, and remove them from your absolute list
对于包含等号 (
=
) 的根路径,此答案无法正常工作。 (感谢 @dbenham 指出这一点。)已编辑: 修复了包含
!
的路径的问题,再次被 @dbenham 发现(谢谢!) .除了计算长度和提取子字符串之外,您还可以使用不同的方法:
存储根路径;
从文件路径中清除根路径。
这是我的尝试(对我有用):
r
变量分配有当前目录。除非当前目录是磁盘驱动器的根目录,否则不会以(不再是这种情况,因为脚本现在读取\
结尾,我们通过附加该字符来修改。__CD__
变量,其值始终以\
结尾(感谢@jeb!),而不是CD
。)< /em>在循环中,我们将当前文件路径存储到 多变的。然后我们输出变量,一路剥离根路径。
This answer will not work correctly with root paths containing equal signs (
=
). (Thanks @dbenham for pointing that out.)EDITED: Fixed the issue with paths containing
!
, again spotted by @dbenham (thanks!).Alternatively to calculating the length and extracting substrings you could use a different approach:
store the root path;
clear the root path from the file paths.
Here's my attempt (which worked for me):
The
r
variable is assigned with the current directory.Unless the current directory is the root directory of a disk drive, it will not end with(No longer the case, as the script now reads the\
, which we amend by appending the character.__CD__
variable, whose value always ends with\
(thanks @jeb!), instead ofCD
.)In the loop, we store the current file path into a variable. Then we output the variable, stripping the root path along the way.
当然,您可以在 Batch 中编写递归算法,使您可以精确控制在每个嵌套子目录中执行的操作:
Of course, you may write a recursive algorithm in Batch that gives you exact control of what you do in every nested subdirectory:
您可以(误)使用
xcopy
命令1 可以列出要复制的文件的相对路径,并具有选项/L
来不复制,而只列出不复制的文件。这将产生如下输出:
目标可以是现有且可访问的驱动器上的任意目录路径,该驱动器不驻留在源目录树中。
请注意,这仅适用于文件,不适用于目录路径。
要删除摘要行
...文件
,让 < code>findstr 将其过滤掉:或者使用
find
以过滤掉此类行:要删除
.\
或驱动器前缀,请捕获xcopy
输出for /F
并使用适当的分隔符:应该很明显如何做驱动器前缀相同:
这是相关的示例输出:
1)基本方法源自此答案由用户MC ND。
You could (mis-)use the
xcopy
command1 that can list relative paths of files to be copied and that features the option/L
to not copy but just list files that would be copied without.This would produce an output like such:
The destination can be an arbitrary directory path on an existing and accessible drive that does not reside within the source directory tree.
Note that this only works with file but not with directory paths.
To delete the summary line
… File(s)
letfindstr
filter it out:Alternatively use
find
to filter such lines out:To remove the
.\
or the drive prefix, capture thexcopy
output withfor /F
and use an appropriate delimiter:It should be quite obvious how to do the same for the drive prefix:
This is the related sample output:
1) The basic approach derives from this answer by user MC ND.