
Я пытаюсь сгенерировать текстовый файл, содержащий имя файла (включая полный путь) и размер файла для всех файлов в определенном каталоге и любом из его подкаталогов (т.е. рекурсивно). В идеале я не хочу запятых в размере файла (но я согласен и на них!)
Следующая команда делает то же самое, но без размера файла:
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 устраняет проблему с «пробелами в именах» в предложении Брайана Эдкинса.
Альтернатива № 3: FORFILES была бы моим выбором, если бы путь не был заключен в двойные кавычки.
Брайан или другие гуру могут иметь более элегантное решение или могут предложить дюжину других решений, но эти три работают. Я пробовал использовать FOR TOKENS, но затем пришлось убрать заголовки и нижние колонтитулы, поэтому я вернулся к варианту № 1. Я также думал создать небольшой файл .bat и вызвать его, но это добавляет еще один файл (хотя это обеспечивает большую гибкость, как и функция).
Я протестировал все варианты с каталогами и именами файлов со встроенными пробелами, с именами файлов длиной более 200 символов, с именами файлов без расширения и в корне небольшого диска (просто ради времени; немного медленно — как и предполагал Брайан — но то же самое происходит и с поиском в проводнике Windows; именно поэтому я установил приложение поиска Everything).
Альтернатива №1: ДЛЯ /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: ДЛЯ /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 сделано заглавным, чтобы прояснить различие между переменной и параметрами переменной, если кто-то выбирает другие имена переменных.
Примечание: добавлено к файлу просто для усмешки, так как OP запросил вывод в файл.
Полагаю, мне действительно следует проверить состояние 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
или . Добавление пустой строки, разделяющей каждый каталог, было бы тривиальным расширением IF.echo off
Осторожность: Использование маски /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: FORFILES. (Риторический вопрос: кавычки — это особенность или недостаток?)
решение3
Я считаю команду «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
Однако я мог правильно видеть специальные символы только в 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 здесь)