2013-10-03 12:50:47 +0000 2013-10-03 12:50:47 +0000
53
53

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

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

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

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)

28
28
28
2013-10-03 13:44:16 +0000

Это должно сработать:

@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
15
15
15
2013-10-03 23:34:41 +0000

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

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

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

Alternative #1: FOR /R

Best(?) Пытаясь выяснить, почему решение Брайана не сработало для меня, я посмотрел на HELP FOR и решил попробовать подход /R. (Создание файла было бы тем же самым, что и в Alternative #2. )

@echo off & for /R "c:\deletelater\folder with spaces" %A in (*.*) do echo %~fA %~zA

Example - Works (другой каталог, чем выше, чтобы продемонстрировать рекурсию)

@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 Spacesnd Name with Spaces.txt 5805492
c:\DeleteLater\Folder with SpacesndNoSpacesLongName.txt 3870322
c:\DeleteLater\FolderNoSpacesrd Name with Spaces.txt 27874695
c:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt 28726032

Альтернатива #2: FOR /F

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

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

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

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

Example - Wrong(Без разделителей; Включает подавление директории на 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\FolderNoSpacesrd
28726032 C:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt 28726032

Example - Исправлено(Вывод заметки на экран, не приложен к файлу)

@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 Spacesnd Name with Spaces.txt 5805492
C:\DeleteLater\Folder with SpacesndNoSpacesLongName.txt 3870322
C:\DeleteLater\FolderNoSpacesrd Name with Spaces.txt 27874695
C:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt 28726032

Альтернатива #3: FORFILES (Quote Issue)

Это решение взято прямо из двух последних примеров в документации 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 *.* не вернет файлы без расширения (как последний файл в примере)!

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

Example - Works (но с полным ходом в кавычках)

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 Spacesnd Name with Spaces.txt" 5805492
"c:\DeleteLater\Folder with SpacesndNoSpacesLongName.txt" 3870322
"c:\DeleteLater\FolderNoSpacesrd Name with Spaces.txt" 27874695
"c:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.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

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

Issue: Путь в Quotes

Итак, есть ли простой способ удалить ненужные(?) кавычки в примере OP и сохранить Альтернативу #3: FORFILES. (Риторический вопрос: Являются ли кавычки особенностью или недостатком?).

1
1
1
2018-03-23 18:47:14 +0000
powershell "dir | select name,length"

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

1
1
1
2014-02-12 12:47:47 +0000

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

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

sfk fromclip > C:\_temp\sfk_list_output.txt

(у меня есть подход с помощью sfk command chaining здесь )

0
0
0
2017-11-11 17:59:32 +0000

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

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 Encoding, сейчас нет времени на анализ). Также я не нашел решения для отображения размера после имени файла. Используйте опции “b” или “k” вместо “h” для отображения размера в байтах или килобайтах. У меня были некоторые проблемы при запуске команды за пределами папки, которую я хочу проанализировать. Так что лучше оба раза вводить команду в нужную директорию (“C:\your_dir” в этом примере) и указывать ее в команде.

0
0
0
2016-07-14 00:19:25 +0000

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

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

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, но в презентации есть определенная ясность, как только вы освоитесь с командной строкой/партийным скриптингом.

0
0
0
2017-01-12 13:48:02 +0000

Я добрался до этого со следующей командой:

(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

P.S. Это основано на ответе BillR (Alternative #1). Однако в моем случае он зависает с @echo off.

-1
-1
-1
2014-09-30 03:41:04 +0000

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

Громкость в диске H - FILES Серийный номер тома C9EB-112E

каталог H:\Files

09/29/2014 11:36 PM 0 тестирования. txt 1 Файл(ы) 0 байт

Каталог H:\Video\Action\Comix

10/06/2012 09:51 AM 184 740 file1.txt 07/20/2012 06:21 AM 864 832 file2.txt 08/31/2009 08:47 PM 606 638 file3.txt 08/31/2009 09:07 PM 160 320 file4.txt

-1
-1
-1
2018-03-22 20:22:09 +0000
where * /t

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

Похожие вопросы

3
19
10
28
1