48

Я пытаюсь сгенерировать текстовый файл, содержащий имя файла (включая полный путь) и размер файла для всех файлов в определенном каталоге и любых его подкаталогах (т.е. рекурсивно). В идеале я не хочу запятых в размере файла (но я согласен на них!)

Следующая команда делает это, но без размера файла:

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 , хотя я бы хотел оказаться неправым. Есть ли другой способ сделать это, используя только команды, доступные из командной строки?

9 ответов9

27

Это должно сделать это:

@echo off & for /f %a in ('dir /s /b') do echo %~fa %~za

Это не очень эффективно ... запускать его для папок, содержащих тонну файлов, может быть отрывочно, поэтому сначала попробуйте на небольших папках.

Из "для /?«текст справки (я использовал« а »вместо« я »)

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
14

Альтернатива № 1: FOR /R является более интуитивным, чем № 2 для меня.
Альтернатива № 2: FOR /F исправляет проблему с "пробелами в именах" в предложении Брайана Адкинса.
Альтернатива № 3: FORFILES будет моим выбором, за исключением того, что путь в двойных кавычках.

У Брайана или других гуру может быть более изящное решение, или он может предложить дюжину других решений, но эти три работают. Я попытался использовать FOR TOKENS, но затем мне пришлось убрать верхние и нижние колонтитулы, поэтому я вернулся к # 1. Я также подумал о создании небольшого файла .bat и его вызове, но это добавляет еще один файл (хотя он обеспечивает большую гибкость, как и функция).

Я проверил все альтернативы с каталогом и именами файлов со встроенными пробелами, 200+ символьными именами файлов, именами файлов без расширений и на корне небольшого диска (только на время; немного медленный - как предложил Брайан - но потом выполняет поиск в проводнике Windows, поэтому я установил приложение «Все для поиска»).

Альтернатива № 1: FOR /R

Лучший(?) Пытаясь выяснить, почему решение Брайана не сработало для меня, я посмотрел на 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

Исправленный ответ :

@echo off & for /f "delims=*" %A in ('dir /s /b') do echo %~fA %~zA 

Более полный ответ с подавлением каталогов и выводом (добавлением) в файл:

@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 = *» указывает символ, не разрешенный в именах файлов.
Примечание: 2-я команда также подавляет каталоги с помощью /a: -d.
Примечание: Сделал заглавную букву имени переменной FOR, чтобы прояснить различие между переменной и параметрами переменной, если кто-то выбирает разные имена переменных.
Примечание: добавляется в файл только для ухмылок, так как ОП запрашивает вывод в файл.

Я полагаю, что мне действительно нужно проверить состояние ECHO и сбросить его.

Проблема - пробелы в именах

Предлагаемое Брайаном решение не обрабатывает имена файлов и папок, содержащие пробелы (по крайней мере, в моей конфигурации Vista).

Пример - Неверно (без разделителей; Включает подавление каталога для OP, но с размером до и после имени файла для выделения)

Сокращенное имя и размер (неверно 4 из 6 файлов):

@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

Обратите внимание, что путь указан в кавычках в выходных данных.
Не имеет значения, echo on или echo off .
Добавление пустой строки, разделяющей каждый каталог, было бы тривиальным расширением IF.

Внимание: использование маски /m *.* Не вернет файлы без расширения (как последний файл в примере)!

В сторону: в каждом каталоге записывается файл с содержимым только этого каталога:
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize >>ForfilesSubOut.txt" Не то, что хотел ОП, но иногда удобно.

Пример - работает (но с полным путём в кавычках)

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: ФОРМЫ. (Риторический вопрос: цитаты - это особенность или недостаток?)

1

Я понимаю, что это требует дополнительной утонченности, но вы можете добиться этого довольно кратко, используя утилиту sfk:

sfk cwd +run -yes "sfk list -size -tab $qfile +toclip"

sfk fromclip > C:\_temp\sfk_list_output.txt

(Я получил подход с использованием цепочки команд sfk здесь)

1
powershell "dir | select name,length"

Это может быть обманом по вопросу ОП. Однако этот вопрос больше не актуален в современных системах на базе Windows. Псевдоним Dir использовался, чтобы помочь нарисовать логическую связь.

0

Я нахожу команду "du" довольно полезной, и она работает как в Windows, так и в Unix (она использовалась для проверки, были ли скопированы все файлы при передаче большого количества данных с ПК с Windows на веб-сервер Linux):

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

Тем не менее, я мог правильно видеть только специальные символы в Блокноте, но не в Блокноте ++ (должно быть, что-то вроде кодировки ANSI/UTF-8, сейчас нет времени на точный анализ). Также я не нашел решения для отображения размера после имени файла. Используйте параметры "b" или "k" вместо "h" для отображения размера в байтах или килобайтах. У меня возникли проблемы при запуске команды вне папки, которую я хочу проанализировать. Поэтому лучше всего ввести команду в правильном каталоге (в этом примере «C:\your_dir») и указать ее в команде.

0

Я достиг этого с помощью следующей команды:

(for /R "\path\to\directory\" %A in (*.*) do echo %~fA %~zA) | findstr /v "echo"

Результат:

D:\Users\Natasha>(for /R ".\" %A in (*.*) do echo %~fA %~zA) | findstr /v "echo"


D:\Users\Natasha\Flowers_ (12).jpg 118886

D:\Users\Natasha\SomeFolder\data.txt 1241

D:\Users\Natasha\SomeFolder\CS\Counter-Strike_1.6.exe 272645624

PS Это основано на ответе BillR (Альтернатива № 1). Однако в моем случае он зависает при @echo off .

0

Ниже приведено то, что я использовал, чтобы найти разные видеофайлы, которые занимали слишком много места на сетевом диске, и записать результаты в текстовый файл на локальном ПК.

Я публикую свой поздний ответ по трем причинам. Во-первых, мне нравятся краткие ответы. Во-вторых, эта единственная строка сценария работала для меня в нескольких настройках, в том числе в сети. Три, согласно неясному комментарию Дона Винса под ответом Брайана Эдкинса, с использованием токенов могут обойти проблемы с именами файлов с пробелами в них.

for /f "tokens=*" %%a in ('dir H:\*.mov H:\*.avi H:\*.wmv H:\*.mp4 /s /b') do echo %%~fa %%~za >> C:\Temp\VideoList.txt

Я заметил, что очень длинные пути к файлам / имена файлов (сотни символов) также могут вызывать ошибки, но поиск не будет зависать от них. Однако путь остается не полностью изученным для ваших целей. После того, как вы заметили, вы можете компенсировать это, углубившись в структуру папок, чтобы устранить эту ошибку.

Эта страница ss64 имеет очень хорошее представление об использовании команды dir , перечисляя все переключатели, множество комбинаций переключателей и показывая несколько полезных примеров правильного синтаксиса. Он не такой всеобъемлющий, как различные сообщества Stack Exchange, но в презентации есть определенная ясность, когда вы освоитесь с командной строкой / пакетным сценарием.

-1
where * /t  

Без чрезмерного усложнения это должно дать желаемый результат. Это даст немного больше, чем запрашивал ОП, но я подумал, что стоит упомянуть. Добавьте ключ /R, чтобы указать каталог, отличный от текущего.

-1

Опустите b в dir /b /s /a: -D> results.txt, и результаты должны выглядеть следующим образом (т.е. dir /s /a: -D> results.txt):

Объем в накопителе H - ФАЙЛЫ. Серийный номер тома - C9EB-112E.

Каталог файлов H:\

29.09.2014 23:36 0 testing.txt 1 Файл (ов) 0 байт

Справочник H:\Video\Action\Comix

06.10.2012 09:51 184 740 file1.txt 20.07.2012 06:21
864 832 file2.txt 31.08.2009 20:47 606 638 file3.txt 31.08.2009 21:07 160 320 file4.txt

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .