Список файлов рекурсивно показывает только полный путь и размер файла из командной строки Windows


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

Ответы:


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

6
Я столкнулся с небольшим препятствием, используя это: файлы с пробелами в имени файла не регистрировались правильно Чтобы исправить это, я добавил "tokens=*" следующее @echo off & for /f "tokens=*" %a in ('dir /s /b') do echo %~fa %~za
Don Vince

Как распечатать это на txt файл?
Saeed Neamati

3
Так должно быть for /r %a in (*) do echo %~fa %~za
ZAB

1
@Saeed Neamati - вот пример >> C:\Temp\VideoList.txt - Результаты любого процесса, предшествующего ранее, записываются в текстовый файл с именем VideoList , Используя один & GT; перезапишет файл ( если он уже существует ) и используя & GT; & GT; добавит новые результаты в конец, если текстовый файл ( если он уже существует ). Если текстовый файл еще не существует, эта команда записывает новый файл с указанным именем.
user23715

это дало мне список файлов * .dwg без размера файла в текстовый файл: @echo off & for /f "tokens=*" %a in ('dir *.dwg /s /b') do echo %~fa >>dwgfiles.txt
CAD bloke

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

Брайан Адкинс предложил: @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 /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
powershell "dir | select name,length"

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


2
Я попробовал это (Windows 7). Запуск занял более 30 секунд (в каталоге с 20 записями), и он не спустился в подкаталоги.
Scott

Чтобы иметь рекурсию, пожалуйста, измените на: powershell "Get-ChildItem -Recurse| select name,length"
giorgiomugnaini

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 имеет очень хорошее представление об использовании реж команда, перечисляющая все переключатели, множество комбинаций переключателей и показывающая несколько полезных примеров правильного синтаксиса. Он не такой всеобъемлющий, как различные сообщества Stack Exchange, но в презентации есть определенная ясность, когда вы освоитесь с командной строкой / пакетным сценарием.


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

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


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») и указать ее в команде.


-1

Опустите b в dir / b / s / a: -D & gt; results.txt и результаты должны выглядеть следующим образом (т.е. dir / s / a: -D & gt; 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 09:07 160 320 file4.txt


Это не ответ на оригинальный вопрос. Он не производит вывод, который он запросил.
DavidPostill

-1
where * /t  

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


1
Попробуйте обновить и подтвердить, что ваш ответ работает так, как я пытался, и получить сообщение об ошибке ERROR: Invalid syntax. Value expected for '/r' так что подумайте о том, чтобы вернуться к чертежной доске и предоставить правильный синтаксис и редактировать Ваш ответ с правильной детализацией.
Pimp Juice IT

Попробуйте ввести значение ... / R - это переключатель каталога, по умолчанию используется текущий каталог, если вы его не указали.
someguy

«Это даст немного больше, чем просил ОП». Вы шутите? where /? говорит: «По умолчанию поиск выполняется по текущему каталогу и в путях, указанных переменной среды PATH ." - Так что ваши where * /t Команда перечисляет каждый файл в C:\Windows\System32некоторые подкаталоги C:\Program Filesи любой другой каталог в PATH, Для меня это было более 3000 строк. Пожалуйста, рассмотрите возможность редактирования своего ответа, чтобы сделать его разумным. Постскриптум Без /Rэто не рекурсивно.
Scott

ГДЕ / Р. *. * работал на меня. /Р . говорит, что искать рекурсивно из указанного местоположения (в данном случае его текущего каталога). *. * - это шаблон для сопоставления. Так что WHERE / R% USERPROFILE% * .docx покажет все файлы слов в папке пользователя. (В этих комментариях надо бежать * с \)
DHW
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.