我正在尝试生成一个文本文件,其中包含特定目录及其任何子目录中所有文件的文件名(包括完整路径)和文件大小(即递归)。理想情况下,我不希望文件大小中有逗号(但我可以接受!)
以下命令可以执行此操作,但不包含文件大小:
dir /b /s /a:-D > results.txt
示例输出如下:
C:\Users\Martin\Pictures\Table\original\PC120013.JPG 227298
C:\Users\Martin\Pictures\Table\original\PC120014.JPG 123234
C:\Users\Martin\Pictures\Table\original\PC120015.JPG 932344
我认为dir
仅使用这种方法是不可能实现的,尽管我很希望证明我错了。还有其他方法可以做到这一点吗?只使用命令提示符中提供的命令?
答案1
这应该可以做到:
@echo off & for /f %a in ('dir /s /b') do echo %~fa %~za
它效率不高...在包含大量文件的文件夹中运行它可能不太可靠,因此请先在小文件夹上尝试一下。
来自“for /?”帮助文本(我使用“a”而不是“I”)
In addition, substitution of FOR variable references has been enhanced.
You can now use the following optional syntax:
%~I - expands %I removing any surrounding quotes (")
%~fI - expands %I to a fully qualified path name
%~dI - expands %I to a drive letter only
%~pI - expands %I to a path only
%~nI - expands %I to a file name only
%~xI - expands %I to a file extension only
%~sI - expanded path contains short names only
%~aI - expands %I to file attributes of file
%~tI - expands %I to date/time of file
%~zI - expands %I to size of file
%~$PATH:I - searches the directories listed in the PATH
environment variable and expands %I to the
fully qualified name of the first one found.
If the environment variable name is not
defined or the file is not found by the
search, then this modifier expands to the
empty string
The modifiers can be combined to get compound results:
%~dpI - expands %I to a drive letter and path only
%~nxI - expands %I to a file name and extension only
%~fsI - expands %I to a full path name with short names only
%~dp$PATH:I - searches the directories listed in the PATH
environment variable for %I and expands to the
drive letter and path of the first one found.
%~ftzaI - expands %I to a DIR like output line
答案2
对我来说,替代方案 #1:FOR /R 比替代方案 #2 更直观。
替代方案 #2:FOR /F 修复了 BrianAdkins 建议中的“名称中有空格”问题。
替代方案 #3:FORFILES 是我的选择,只是路径用双引号引起来。
Brian 或其他专家可能有更优雅的解决方案,或者可以提出十几个其他解决方案,但这三个是可行的。我尝试使用 FOR TOKENS,但后来不得不删除页眉和页脚,所以我又回到了 #1。我还考虑过创建一个小的 .bat 文件并调用它,但这会添加另一个文件(尽管它确实提供了更大的灵活性,就像函数一样)。
我测试了所有替代方案,包括带有嵌入空格的目录和文件名、超过 200 个字符的文件名、没有扩展名的文件名以及位于小型驱动器的根目录(只是为了节省时间;有点慢 - 正如 Brian 建议的那样 - 但在 Windows 资源管理器中搜索也是如此;这就是我安装 Everything 搜索应用程序的原因)。
替代方案 1:FOR /R
最好的(?)在试图弄清楚为什么 Brian 的解决方案对我不起作用时,我查看了 HELP FOR 并决定尝试 /R 方法。(创建文件与替代方案 #2 相同。)
@echo off & for /R "c:\deletelater\folder with spaces" %A in (*.*) do echo %~fA %~zA
示例 - 工作原理(与上面不同的目录来演示递归)
@echo off & for /R "c:\deletelater" %A in (*.*) do echo %~fA %~zA
c:\DeleteLater\Name with Spaces.txt 19800676
c:\DeleteLater\NoSpacesLongName.txt 21745440
c:\DeleteLater\Folder with Spaces\2nd Name with Spaces.txt 5805492
c:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt 3870322
c:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt 27874695
c:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032
替代方案2:FOR /F
BrianAdkins 建议:@echo off & for /f %a in ('dir /s /b') do echo %~fa %~za
A更正答案是:
@echo off & for /f "delims=*" %A in ('dir /s /b') do echo %~fA %~zA
A更加完整抑制目录并输出(附加)到文件的答案是:
@echo Results on %DATE% for %CD% >> YourDirFile.txt & echo off & for /f "delims=*" %A in ('dir /s /b /a:-d') do echo %~fA %~zA >> YourDirFile.txt
注意:“delims=*”指定文件名中不允许的字符。
注意:第二个命令还通过 /a:-d 隐藏目录。
注意:如果有人选择不同的变量名,请将 FOR 变量名大写,以明确变量和变量参数之间的区别。
注意:附加到文件只是为了好玩,因为 OP 要求输出到文件。
我想我真的应该检查 ECHO 的状态并将其重置。
问题 - 名称中的空格
Brian 提出的解决方案不处理包含空格的文件和文件夹名称(至少在我的 Vista 配置中不行)。
示例 - 错误 (没有分隔符;包括每个 OP 抑制目录但为了强调文件名前后的大小)
名称和大小被截断(6 个文件中有 4 个不正确):
@echo off & for /f %A in ('dir /s /b /a:-d') do echo %~zA %~fA %~zA
C:\DeleteLater\Name
21745440 C:\DeleteLater\NoSpacesLongName.txt 21745440
C:\DeleteLater\Folder
C:\DeleteLater\Folder
C:\DeleteLater\FolderNoSpaces\3rd
28726032 C:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032
示例 - 正确 (注意输出到屏幕,而不是附加到文件)
@echo off & for /f "delims=*" %A in ('dir /s /b /a:-d') do echo %~fA %~zA
C:\DeleteLater\Name with Spaces.txt 19800676
C:\DeleteLater\NoSpacesLongName.txt 21745440
C:\DeleteLater\Folder with Spaces\2nd Name with Spaces.txt 5805492
C:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt 3870322
C:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt 27874695
C:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032
替代方案 #3:FORFILES(引文问题)
该解决方案直接取自 FORFILES 文档中的最后两个示例(forfiles /?
)。
FORFILES /S /M *.doc /C "cmd /c echo @fsize"
FORFILES /M *.txt /C "cmd /c if @isdir==FALSE notepad.exe @file"
结合这些例子并写入文件可以得到答案(几乎):
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize" >>ForfilesOut.txt
请注意,输出中的路径用引号引起来。无论是否切换,
都无关紧要。 添加一个空白行来分隔每个目录将是 IF 的简单扩展。echo on
echo off
警告:使用掩码/m *.*
将不会返回没有扩展名的文件(如示例中的最后一个文件)!
在旁边:这会在每个目录中写入一个文件,其中包含该目录的内容:这
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize >>ForfilesSubOut.txt"
不是 OP 想要的,但有时很方便。
示例 - 工作原理(但完整路径用引号括起来)
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize"
"c:\DeleteLater\Name with Spaces.txt" 19800676
"c:\DeleteLater\NoSpacesLongName.txt" 21745440
"c:\DeleteLater\Folder with Spaces\2nd Name with Spaces.txt" 5805492
"c:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt" 3870322
"c:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt" 27874695
"c:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt" 28726032
"c:\DeleteLater\MoreFiles\A really really long file name that goes on and on 123456789 asdfghjkl zxcvnm qwertyuiop and still A really really long file name that goes on and on 123456789 qwertyuiop and still further roughly 225 characters by now.txt" 447
"c:\DeleteLater\MoreFiles\New Text Document no extension" 0
此示例包含一个带有超长文件名和没有扩展名的文件名的额外目录。
问题:引号中的路径
那么,有没有一种简单的方法可以删除 OP 示例中不需要的引号并保存替代方案 #3:FORFILES。(反问:引号是特点还是缺陷?)
答案3
我发现“du”命令非常有用,它适用于 Windows 和 Unix(在从 Windows PC 向 Linux Web 服务器传输大量数据时使用它来检查所有文件是否都已被复制):
du -ah "C:\your_dir" > "C:\file_list.txt"
输出:
15 C:\your_dir/.htaccess
608 C:\your_dir/folder/hello.txt
1.0 C:\your_dir/folder/subfolder/test.txt
1.0 C:\your_dir/folder/subfolder
1.2M C:\your_dir/folder/world.txt
1.2M C:\your_dir/folder
9.0 C:\your_dir/no_file_ending
11 C:\your_dir/sample document 1.txt
684K C:\your_dir/sample document 2 - äöüßÄÖÜáà.txt
1.9M C:\your_dir
但是,我只能在 Notepad 中正确看到特殊字符,而在 Notepad++ 中则无法正确看到(一定是 ANSI/UTF-8 编码的问题,现在没时间进行准确分析)。另外,我也没有找到在文件名后显示大小的解决方案。使用“b”或“k”选项代替“h”以显示字节或千字节大小。在要分析的文件夹外运行命令时,我遇到了一些麻烦。因此,最好在正确的目录中输入命令(本例中为“C:\your_dir”)并在命令中指定它。
答案4
我意识到这需要额外的工具,但你可以使用sfk 实用程序:
sfk cwd +run -yes "sfk list -size -tab $qfile +toclip"
sfk fromclip > C:\_temp\sfk_list_output.txt
(我使用的方法sfk 命令链在这里)