Как извлечь полный список типов расширений в каталоге?

28

Внутри каталога и рекурсивно в его подкаталогах, что означает, что каждый каталог в каталоге обрабатывается, как мне составить полный список уникальных расширений в каталоге?

ОС - это Windows XP со всеми текущими обновлениями, но я могу запустить скрипт, если смогу рассказать, что он делает, хотя я бы предпочел не устанавливать dot-net, так как он мне действительно не нравится.

просчеты
источник

Ответы:

29

Этот пакетный скрипт сделает это.

@echo off

set target=%~1
if "%target%"=="" set target=%cd%

setlocal EnableDelayedExpansion

set LF=^


rem Previous two lines deliberately left blank for LF to work.

for /f "tokens=*" %%i in ('dir /b /s /a:-d "%target%"') do (
    set ext=%%~xi
    if "!ext!"=="" set ext=FileWithNoExtension
    echo !extlist! | find "!ext!:" > nul
    if not !ERRORLEVEL! == 0 set extlist=!extlist!!ext!:
)

echo %extlist::=!LF!%

endlocal

Сохраните его как любой .batфайл и запустите его с помощью команды batchfile(замените то, что вы назвали), чтобы отобразить текущий каталог, или укажите путь с помощью batchfile "path". Будет искать все подкаталоги.

Если вы хотите экспортировать в файл, используйте batchfile >filename.txt(или batchfile "path" >filename.txt).

объяснение

Все, что находится перед for /f...строкой, просто настраивает: он ищет целевой каталог для поиска, включает отложенное расширение, что позволяет мне обновлять переменные в цикле и определяет newline ( LF), который я могу использовать для более точного вывода. Да, и %~1означает «получить первый аргумент, удаляя кавычки», который предотвращает двойные кавычки - см for /?.

Цикл использует это dir /b /s /a:-d "%target%" команду, собирая список всех файлов во всех подкаталогах под целью.

%%~xiизвлекает расширение из полных путей, которые dirвозвращает команда.

Пустое расширение заменяется на «FileWithNoExtension», так что вы знаете, что такой файл существует - если я добавил пустую строку вместо этого, это не так очевидно.

Весь текущий список при отправке через findкоманду, чтобы обеспечить уникальность. Текстовый вывод команды find отправляется nul, по сути, в черную дыру - нам это не нужно. Поскольку мы всегда добавляем a :в конец списка, мы также должны убедиться, что поисковый запрос заканчивается на, :чтобы он не совпадал с частичными результатами - см. Комментарии.

% ERRORLEVEL% устанавливается findкомандой, значение 0 указывает на совпадение. Так что, если это не 0, текущее расширение пока отсутствует в списке и должно быть добавлено.

Линия эха в основном выводит, и я также заменяю свои заполнители ( :) на новые строки, чтобы они выглядели хорошо.

боб
источник
+1 @Bob: Удивительный ответ, добавление объяснения тоже очень помогло. Только что протестировал скрипт, пересмотрел результаты теста, и все отлично заработало. Еще раз спасибо!
промахи
1
Сработало ОТЛИЧНО! Я использовал следующий синтаксис:batchfile "path" >filename.txt
lucaferrario
Отличный сценарий! Но в этом есть небольшая ошибка: если папка содержит файлы aaa.cssи zzz.cs, расширение .csне сообщит сценарий.
Goozak
1
@ Goozak Упс. Исправлено сейчас. Чудеса текстового поиска ... должны были убедиться, что поисковый запрос закончился, :чтобы заставить его соответствовать границам.
Боб
19

Несмотря на то, что он не соответствует требованиям для пакетного сценария, я использовал однострочный сценарий powershell:

Get-Childitem C:\MyDirectory -Recurse | WHERE { -NOT $_.PSIsContainer } | Group Extension -NoElement | Sort Count -Desc > FileExtensions.txt

Вы можете запустить его из командной строки / командного файла:

Powershell -Command "& Get-Childitem C:\MyDirectory -Recurse | WHERE { -NOT $_.PSIsContainer } | Group Extension -NoElement | Sort Count -Desc > FileExtensions.txt"

Я не претендую на кредит, и, конечно, вам понадобится установленный Powershell. Для более новых версий Windows это не обходится.

Если вы удалите C:\MyDirectoryего, он будет выполняться в текущем каталоге.

В конце он создаст FileExtensions.txt, содержащий что-то вроде следующего:

+-------+------+
| Count | Name |
+-------+------+
| ----- | ---- |
| 8216  | .xml |
| 4854  | .png |
| 4378  | .dll |
| 3565  | .htm |
| ...   | ...  |
+-------+------+

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

Get-ChildItem : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

Любые подкаталоги там также не будут анализироваться, но результаты для всего остального будут отображаться.

Дэн Аткинсон
источник
Спасибо, согласитесь, это полезный ответ. На несвязанной ноте немного озадачен тем, что вы разместили только один ответ, но при этом имеете значок «Фанатик» для посещения Superuser в течение 100 дней подряд. У вас есть сайт в закладки или что-то?
промахи
Знак был вручен в 2010 году, когда я эффективно скрывался, но я гораздо активнее в SO: stackoverflow.com/users/31532/dan-atkinson . :)
Дэн Аткинсон
4

Вот подробный ответ с помощью PowerShell (в Windows XP вам придется установить PowerShell):

Эй, автор сценариев! Как я могу использовать Windows PowerShell для выбора уникальных расширений файлов, используемых в коллекции файлов?

RichardM
источник
1
Хотя PowerShell определенно намного проще, чем командная строка, он основан на .NET. Что, к сожалению, идет вразрез с «я бы предпочел не устанавливать dot-net».
Боб
1
+1 @RichardM: согласен с Бобом. Кроме того, код, связанный с подсчетом найденных экземпляров расширений - ничего не зная о PowerShell - выглядит очень загруженным; Я имею в виду, что вместо того, чтобы просто вести подсчет каждого экземпляра, я считаю, что нужно создать массив для хранения дубликатов экземпляров расширения для каждого расширения, а затем выполнить подсчет для каждого массива расширений в конце, что мне кажется очень странным способом подсчет расширений Я что-то пропустил? (Тем не менее, первая однострочная оболочка PowerShell хороша, и я бы попробовал ее, если бы мне не нравился dotnet.)
промахи
1
Это честно. Этот вопрос может привлечь пользователей, которые более открыты для решения PowerShell. Имейте в виду, достойный поиск Google также найдет вышеуказанную ссылку.
RichardM
3
+1 за эту ссылку. Грубые ошибки явно не нравятся .net, но это не значит, что приведенное выше решение является лучшим долгосрочным решением этой проблемы. Чем больше языков, тем лучше я думаю.
Стив Рэтбоун
1
Вот еще одна ссылка, которая обращается к рекурсивному поиску с использованием powershell. robertbigec.wordpress.com/2011/01/07/…
goodeye
0

Чтобы получить список всех уникальных расширений из cmd по пути, который вы используете:

Powershell -Command "Get-ChildItem . -Include *.* -Recurse | Select-Object Extension | Sort-Object -Property Extension -Unique"
kofifus
источник
0

Я нашел полезным изменить

if "!ext!"=="" set ext=FileWithNoExtension

в

if "!ext!"=="" set ext=.FileWithNoExtension

и изменить

echo %extlist::=!LF!%

в

echo %extlist::=!LF!% > ext-list.txt

Сгенерированный файл содержит (без перевода строки, но не имеет значения) .bat.pdf.skp.ai.png.jpg.tif.pcp.txt.lst.ttf.dfont.psd.indd.docx.PDF.JPG.gif.jpeg .dwg.exr.FileWithNoExtension.vrlmap.sat.bak.ctb

который я тогда смог использовать для своего проекта.

Steev43230
источник