Jak wyodrębnić pełną listę typów rozszerzeń w katalogu?

28

W obrębie katalogu i rekurencyjnie w jego podkatalogach, co oznacza, że ​​każdy katalog w katalogu jest przetwarzany, jak skompilować pełną listę unikalnych rozszerzeń w katalogu?

System operacyjny to Windows XP ze wszystkimi aktualnymi aktualizacjami, ale mogę uruchomić skrypt, jeśli mogę powiedzieć, co robi, ale wolałbym nie instalować dot-net, ponieważ naprawdę mi się nie podoba.

błędy
źródło

Odpowiedzi:

29

Ten skrypt wsadowy to zrobi.

@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

Zapisz go jako dowolny .batplik i uruchom go za pomocą polecenia batchfile(zastąp go tym, co go nazwałeś), aby wyświetlić bieżący katalog lub podaj ścieżkę batchfile "path". Przeszuka wszystkie podkatalogi.

Jeśli chcesz wyeksportować do pliku, użyj batchfile >filename.txt(lub batchfile "path" >filename.txt).

Wyjaśnienie

Wszystko przed for /f...wierszem po prostu konfiguruje: pobiera katalog docelowy do przeszukiwania, umożliwia opóźnione rozszerzanie, co pozwala mi aktualizować zmienne w pętli i definiuje znak nowej linii ( LF) , którego można użyć do uzyskania ładniejszych wyników. Aha, a %~1oznacza „pobierz pierwszy argument, usuwając cudzysłowy”, co zapobiega podwojonym cudzysłowom - patrz for /?.

Pętla używa tego dir /b /s /a:-d "%target%"polecenia, pobierając listę wszystkich plików we wszystkich podkatalogach pod celem.

%%~xiwyodrębnia rozszerzenie z pełnych ścieżek dirzwracanych przez polecenie.

Puste rozszerzenie jest zastępowane przez „FileWithNoExtension”, więc wiesz, że istnieje taki plik - jeśli zamiast tego dodam pustą linię, nie jest to tak oczywiste.

Cała bieżąca lista, jeśli zostanie wysłana za pomocą findpolecenia, w celu zapewnienia wyjątkowości. Dane wyjściowe polecenia find są wysyłane do nulczarnej dziury - nie chcemy tego. Ponieważ zawsze dodajemy znak „ :na końcu listy”, należy również upewnić się, że wyszukiwane hasło kończy się znakiem „ :tak”, aby nie pasowało do częściowych wyników - patrz komentarze.

% ERRORLEVEL% jest ustawiane przez findkomendę, wartość 0 oznacza, że ​​było dopasowanie. Więc jeśli nie jest to 0, obecne rozszerzenie nie znajduje się dotychczas na liście i powinno zostać dodane.

Linia echa generalnie generuje, a także zastępuję moje symbole zastępcze ( :) nowymi liniami, aby wyglądały ładnie.

Kok
źródło
+1 @Bob: Niesamowita odpowiedź, dodanie wyjaśnienia również było ogromną pomocą. Właśnie przetestowałem skrypt, przejrzał wyniki testu i wszystko działało świetnie. Jeszcze raz dzięki!
błąka się
1
Działało IDEALNIE! Użyłem następującej składni:batchfile "path" >filename.txt
lucaferrario,
Świetny scenariusz! Jest jednak mały błąd: jeśli folder zawiera pliki aaa.cssi zzz.cs, .csskrypt nie zgłosi rozszerzenia .
Goozak,
1
@ Goozak Whoops. Naprawiono teraz. Cuda przeszukiwania tekstu ... musiały się upewnić, że zapytanie zakończyło się, :aby wymusić dopasowanie do granic.
Bob
19

Chociaż nie jestem ściśle zgodny z wymaganiami dla skryptu wsadowego, użyłem jednowierszowego skryptu PowerShell:

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

Możesz potencjalnie uruchomić go z wiersza poleceń / pliku wsadowego:

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

Nie żądam za to uznania i oczywiście będziesz potrzebować zainstalowanego programu PowerShell. W przypadku nowszych wersji systemu Windows nie można tego obejść.

Jeśli C:\MyDirectorygo usuniesz , zostanie on uruchomiony w bieżącym katalogu.

Na koniec wygeneruje FileExtensions.txt zawierający coś takiego:

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

W zależności od struktury folderów mogą się czasem pojawiać błędy informujące o długiej ścieżce.

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.

Wszystkie podkatalogi również nie zostaną przeanalizowane, ale wyniki dla wszystkich pozostałych elementów nadal będą wyświetlane.

Dan Atkinson
źródło
Dzięki, zgódź się, że to przydatna odpowiedź. W niepowiązanej notatce nieco zastanawiałem się, jak opublikowałeś tylko jedną odpowiedź, a mimo to masz odznakę „Fanatyk” za odwiedzanie Superużytkownika przez 100 kolejnych dni. Czy masz stronę z zakładkami?
wpadki
Odznaka została przyznana w 2010 roku, kiedy skutecznie czaiłem się, ale jestem znacznie bardziej aktywny na SO: stackoverflow.com/users/31532/dan-atkinson . :)
Dan Atkinson
4

Oto szczegółowa odpowiedź przy użyciu programu PowerShell (w systemie Windows XP trzeba zainstalować program PowerShell):

Hej, Skrypciarze! Jak użyć programu Windows PowerShell do wybrania unikalnych rozszerzeń plików używanych w kolekcji plików?

RichardM
źródło
1
Chociaż PowerShell jest zdecydowanie łatwiejszy niż wiersz poleceń, jest oparty na .NET. Co niestety jest sprzeczne z „Wolałbym nie instalować kropki”.
Bob
1
+1 @RichardM: Zgadzam się z Bobem. Ponadto kod związany z liczeniem znalezionych wystąpień rozszerzeń - nie wiedząc nic o PowerShell - wydaje się bardzo obciążony pamięci; co oznacza, że ​​zamiast utrzymywać liczbę wszystkich wystąpień, wydaje mi się, że utworzenie tablicy do przechowywania duplikatów wystąpień rozszerzenia dla każdego rozszerzenia, a następnie wykonanie liczby dla każdej tablicy rozszerzeń na końcu, co wydaje mi się bardzo dziwnym sposobem liczenie wystąpień rozszerzeń. Czy coś brakuje? (To powiedziawszy, pierwszy jedno-liniowy PowerShell jest fajny i spróbowałbym go, gdybym nie lubił dotnet.)
obleka
1
To uczciwe. To pytanie może przyciągnąć użytkowników, którzy są bardziej otwarci na rozwiązanie PowerShell. Pamiętaj, że porządna wyszukiwarka Google również znajdzie powyższy link.
RichardM,
3
+1 dla tego linku. błędy oczywiście nie podoba się wszystkim .net, ale to nie znaczy, że powyższe rozwiązanie jest najlepszym długoterminowym rozwiązaniem tego problemu. Im więcej języków, tym lepiej.
Steve Rathbone
1
Oto kolejny link do wyszukiwania rekurencyjnego za pomocą programu PowerShell. robertbigec.wordpress.com/2011/01/07/…
goodeye
0

Aby wyświetlić listę wszystkich unikalnych rozszerzeń z cmd pod ścieżką, z której korzystasz:

Powershell -Command "Get-ChildItem . -Include *.* -Recurse | Select-Object Extension | Sort-Object -Property Extension -Unique"
Kofifus
źródło
0

Uznałem, że warto to zmienić

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

do

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

i zmienić

echo %extlist::=!LF!%

do

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

Wygenerowany plik zawierał (nie ma linii, ale nie ma znaczenia) .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

które mogłem następnie wykorzystać w moim projekcie.

Steev43230
źródło