Comment extraire une liste complète des types d'extensions dans un répertoire?

28

Dans un répertoire, et récursivement dans ses sous-répertoires, ce qui signifie que chaque répertoire d'un répertoire est traité, comment puis-je compiler une liste complète d'extensions uniques dans le répertoire?

Le système d'exploitation est Windows XP avec toutes les mises à jour actuelles, mais je peux exécuter un script si je peux dire ce qu'il fait, bien que je préfère ne pas avoir à installer dot-net, car je ne l'aime vraiment pas.

bévues
la source

Réponses:

29

Ce script batch le fera.

@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

Enregistrez-le sous n'importe quel .batfichier et exécutez-le avec la commande batchfile(remplacez ce que vous avez nommé) pour répertorier le répertoire en cours ou spécifiez un chemin avec batchfile "path". Il recherchera tous les sous-répertoires.

Si vous souhaitez exporter vers un fichier, utilisez batchfile >filename.txt(ou batchfile "path" >filename.txt).

Explication

Tout ce qui précède la for /f...ligne ne fait que mettre les choses en place: il obtient le répertoire cible à rechercher, active l' expansion retardée qui me permet de mettre à jour les variables dans la boucle et définit une nouvelle ligne ( LF) que je peux utiliser pour une sortie plus nette. Oh, et le %~1moyen "obtenir le premier argument, supprimer les guillemets" qui empêche les guillemets doublés - voir for /?.

La boucle utilise cette dir /b /s /a:-d "%target%"commande, récupérant une liste de tous les fichiers dans tous les sous-répertoires sous la cible.

%%~xiextrait l'extension des chemins complets renvoyés par la dircommande.

Une extension vide est remplacée par "FileWithNoExtension", donc vous savez qu'il existe un tel fichier - si j'ai ajouté une ligne vide à la place, ce n'est pas aussi évident.

Toute la liste actuelle si elle est envoyée via une findcommande, pour garantir l'unicité. La sortie texte de la commande find est envoyée à nul, essentiellement un trou noir - nous n'en voulons pas. Comme nous ajoutons toujours un :à la fin de la liste, nous devons également nous assurer que la requête de recherche se termine par un :afin qu'elle ne corresponde pas aux résultats partiels - voir les commentaires.

% ERRORLEVEL% est défini par la findcommande, une valeur de 0 indique une correspondance. Donc, si ce n'est pas 0, l'extension actuelle n'est pas sur la liste jusqu'à présent et devrait être ajoutée.

La ligne d'écho sort essentiellement, et je remplace également mes espaces réservés ( :) par des sauts de ligne pour les rendre agréables.

Bob
la source
+1 @Bob: réponse étonnante, l'ajout de l'explication a également été d'une grande aide. Je viens de tester le script, de revoir les résultats du test, et tout fonctionnait très bien. Merci encore!
bévue
1
Cela a fonctionné PARFAITEMENT! J'ai utilisé la syntaxe suivante:batchfile "path" >filename.txt
lucaferrario
Grand script! Mais il y a un petit bug avec: si le dossier contient des fichiers aaa.csset zzz.cs, l'extension .csne sera pas signalée par le script.
Goozak
1
@Goozak Whoops. Fixé maintenant. Les merveilles de la recherche de texte ... devaient s'assurer que la requête de recherche se terminait par :pour la forcer à correspondre aux limites.
Bob
19

Bien que ne répondant pas strictement à l'exigence d'un script batch, j'ai utilisé un script powershell sur une seule ligne:

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

Vous pouvez potentiellement l'exécuter à partir de la ligne de commande / fichier batch:

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

Je ne demande aucun crédit pour cela, et bien sûr, vous aurez besoin d'installer Powershell. Pour les nouvelles versions de Windows, il n'y a aucun moyen de contourner cela.

Si vous le supprimez, C:\MyDirectoryil s'exécutera dans le répertoire courant.

À la fin, il produira un FileExtensions.txt contenant quelque chose comme ceci:

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

En fonction de la structure de votre dossier, vous pouvez parfois obtenir des erreurs vous informant que votre chemin est long.

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.

Tous les sous-répertoires ne seront pas analysés mais les résultats pour tout le reste seront toujours affichés.

Dan Atkinson
la source
Merci, convenez que c'est une réponse utile. Sur une note sans rapport, un peu perplexe sur la façon dont vous avez publié une seule réponse, tout en ayant le badge "Fanatic" pour visiter le superutilisateur pendant 100 jours consécutifs. Avez-vous le site en signet ou quelque chose?
bévues
Le badge a été décerné en 2010 lorsque je me cachais effectivement, mais je suis beaucoup plus actif sur SO: stackoverflow.com/users/31532/dan-atkinson . :)
Dan Atkinson
4

Voici une réponse détaillée à l'aide de PowerShell (avec Windows XP, vous devrez installer PowerShell):

Hé, le scripteur! Comment puis-je utiliser Windows PowerShell pour sélectionner les extensions de fichier uniques utilisées dans une collection de fichiers?

RichardM
la source
1
Bien que PowerShell soit nettement plus facile que la ligne de commande, il est basé sur .NET. Ce qui, malheureusement, va à l'encontre de "Je préférerais ne pas avoir à installer dot-net".
Bob
1
+1 @RichardM: d'accord avec Bob. En outre, le code lié au comptage des instances d'extension trouvées - ne sachant rien sur PowerShell - semble très lourd en mémoire; ce qui signifie qu'au lieu de simplement compter un nombre de chaque instance, je pense que créer un tableau pour stocker les instances en double d'une extension pour chaque extension, puis faire un compte pour chaque tableau d'extension à la fin, ce qui me semble être une façon très étrange de compter les instances d'extension. Suis-je en train de manquer quelque chose? (Cela dit, le premier PowerShell un revêtement est agréable, et je voudrais l' essayer si je n'aime pas DotNet.)
gaffes
1
C'est juste. Cette question peut attirer les chercheurs qui sont plus ouverts à une solution PowerShell. Attention, une recherche Google décente trouvera également le lien ci-dessus.
RichardM
3
+1 pour ce lien. les erreurs évidentes n'aiment pas tout .net, mais cela ne signifie pas que la solution ci-dessus est la meilleure solution à long terme à ce problème. Plus il y a de langues, mieux je pense.
Steve Rathbone
1
Voici un autre lien qui traite de la recherche récursive, utilisant powershell. robertbigec.wordpress.com/2011/01/07/…
goodeye
0

Pour répertorier toutes les extensions uniques de cmd sous le chemin que vous utilisez:

Powershell -Command "Get-ChildItem . -Include *.* -Recurse | Select-Object Extension | Sort-Object -Property Extension -Unique"
kofifus
la source
0

J'ai trouvé utile de changer

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

à

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

et changer

echo %extlist::=!LF!%

à

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

Le fichier généré contenait (pas de sauts de ligne, mais peu importe) .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

que j'ai ensuite pu utiliser pour mon projet.

Steev43230
la source