Wie extrahiere ich eine vollständige Liste der Erweiterungstypen in einem Verzeichnis?

28

Wie erstelle ich innerhalb eines Verzeichnisses und rekursiv innerhalb seiner Unterverzeichnisse, dh jedes Verzeichnis innerhalb eines Verzeichnisses wird verarbeitet, eine vollständige Liste eindeutiger Erweiterungen innerhalb des Verzeichnisses?

Betriebssystem ist Windows XP mit allen aktuellen Updates, aber ich kann ein Skript ausführen, wenn ich in der Lage bin zu sagen, was es tut, obwohl ich es vorziehen würde, dot-net nicht installieren zu müssen, da es mir wirklich nicht gefällt.

Fehler
quelle

Antworten:

29

Dieses Batch-Skript erledigt das.

@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

Speichern Sie es als eine beliebige .batDatei und führen Sie es mit dem Befehl aus batchfile(ersetzen Sie das, was Sie es genannt haben), um das aktuelle Verzeichnis aufzulisten, oder geben Sie einen Pfad mit an batchfile "path". Es werden alle Unterverzeichnisse durchsucht.

Wenn Sie in eine Datei exportieren möchten, verwenden Sie batchfile >filename.txt(oder batchfile "path" >filename.txt).

Erläuterung

Alles, bevor die for /f...Zeile eingerichtet wird: Das Zielverzeichnis wird durchsucht, eine verzögerte Erweiterung aktiviertLF , mit der ich Variablen in der Schleife aktualisieren und eine neue Zeile ( ) definieren kann, die für eine übersichtlichere Ausgabe verwendet werden kann. Oh, und die %~1Mittel "Holen Sie sich das erste Argument, entfernen Sie Anführungszeichen", die doppelte Anführungszeichen verhindert - siehe for /?.

Die Schleife verwendet diesen dir /b /s /a:-d "%target%"Befehl und ruft eine Liste aller Dateien in allen Unterverzeichnissen unter dem Ziel ab.

%%~xiextrahiert die Erweiterung aus den vollständigen Pfaden, die der dirBefehl zurückgibt.

Eine leere Erweiterung wird durch "FileWithNoExtension" ersetzt, sodass Sie wissen, dass es eine solche Datei gibt. Wenn ich stattdessen eine leere Zeile hinzufüge, ist dies nicht ganz so offensichtlich.

Die gesamte aktuelle Liste wird über einen findBefehl gesendet , um die Eindeutigkeit sicherzustellen. Die Textausgabe des Befehls find wird an nulein Schwarzes Loch gesendet - wir wollen es nicht. Da wir immer ein :am Ende der Liste anhängen , sollten wir auch sicherstellen, dass die Suchanfrage mit einem endet, :damit sie nicht mit Teilergebnissen übereinstimmt - siehe Kommentare.

% ERRORLEVEL% wird vom findBefehl festgelegt. Der Wert 0 gibt an, dass eine Übereinstimmung vorliegt . Wenn es also nicht 0 ist, ist die aktuelle Erweiterung noch nicht in der Liste und sollte hinzugefügt werden.

Die Echo-Zeile wird im Grunde genommen ausgegeben, und ich ersetze meine Platzhalter ( :) durch Zeilenumbrüche, damit sie gut aussehen.

Bob
quelle
+1 @ Bob: Erstaunliche Antwort, das Hinzufügen der Erklärung war auch eine große Hilfe. Habe gerade das Skript getestet, die Testergebnisse überprüft und alles hat super funktioniert. Noch einmal Danke!
Fehler
1
Es hat perfekt funktioniert! Ich habe die folgende Syntax verwendet:batchfile "path" >filename.txt
Lucaferrario
Tolles Drehbuch! Es gibt jedoch einen kleinen Fehler: Wenn der Ordner Dateien aaa.cssund enthält zzz.cs, wird die Erweiterung .csvom Skript nicht gemeldet.
Goozak,
1
@ Goozak Whoops. Jetzt behoben. Die Wunder der Textsuche ... mussten sicherstellen, dass die Suchanfrage mit endete :, damit sie den Grenzen entsprach.
Bob
19

Ich habe ein einzeiliges Powershell-Skript verwendet, obwohl es die Anforderungen für ein Batch-Skript nicht strikt erfüllt:

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

Sie können es möglicherweise über die Befehlszeile / Batch-Datei ausführen:

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

Ich beanspruche keine Gutschrift dafür, und natürlich müssen Sie Powershell installiert haben. Für neuere Versionen von Windows gibt es keine Möglichkeit, dies zu umgehen.

Wenn Sie es entfernen C:\MyDirectory, wird es im aktuellen Verzeichnis ausgeführt.

Am Ende wird eine FileExtensions.txt erstellt, die etwa Folgendes enthält:

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

Abhängig von Ihrer Ordnerstruktur können gelegentlich Fehler auftreten, die darauf hinweisen, dass Sie einen langen Pfad haben.

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.

Alle darin enthaltenen Unterverzeichnisse werden ebenfalls nicht analysiert, die Ergebnisse für alle anderen werden jedoch weiterhin angezeigt.

Dan Atkinson
quelle
Danke, ich bin damit einverstanden, dass es eine nützliche Antwort ist. Was nichts damit zu tun hat, ist etwas verwirrt darüber, dass Sie nur eine einzige Antwort gepostet haben und dennoch das "Fanatic" -Abzeichen für den Besuch des Superuser an 100 aufeinanderfolgenden Tagen haben. Haben Sie die Site mit einem Lesezeichen versehen oder so?
Fehler
Das Abzeichen wurde 2010 verliehen, als ich effektiv lauerte, aber ich bin viel aktiver bei SO: stackoverflow.com/users/31532/dan-atkinson . :)
Dan Atkinson
4

Hier ist eine ausführliche Antwort mit PowerShell (unter Windows XP müssen Sie PowerShell installieren):

Hey, Scripting Guy! Wie kann ich mit Windows PowerShell die eindeutigen Dateierweiterungen auswählen, die in einer Dateisammlung verwendet werden?

RichardM
quelle
1
Während PowerShell definitiv viel einfacher als die Befehlszeile ist, basiert es auf .NET. Was leider gegen "Ich würde es vorziehen, nicht dot-net installieren zu müssen" spricht.
Bob
1
+1 @RichardM: Stimme Bob zu. Außerdem ist der Code für die Zählung der gefundenen Erweiterungsinstanzen, der nichts über PowerShell weiß, sehr speicherintensiv. Das heißt, anstatt nur eine Zählung jeder Instanz zu erstellen, ist es meiner Meinung nach ein Array zu erstellen, um doppelte Instanzen einer Erweiterung für jede Erweiterung zu speichern, und dann am Ende eine Zählung für jedes Erweiterungsarray durchzuführen, was für mich eine sehr seltsame Art zu sein scheint Zählen von Erweiterungsinstanzen. Vermisse ich etwas? (Das heißt, der erste PowerShell-Einzeiler ist nett, und ich würde es versuchen, wenn ich Dotnet nicht mag.)
Fehler
1
Das ist fair. Diese Frage könnte Sucher anziehen, die offener für eine PowerShell-Lösung sind. Wohlgemerkt, eine anständige Google-Suche findet den obigen Link ebenfalls.
RichardM
3
+1 für diesen Link. Fehler offensichtlich mögen nicht alles .net, aber das bedeutet nicht, dass die oben genannte Lösung die beste langfristige Lösung für dieses Problem ist. Je mehr Sprachen, desto besser denke ich.
Steve Rathbone
1
Hier ist ein weiterer Link, der die rekursive Suche mithilfe von Powershell behandelt. robertbigec.wordpress.com/2011/01/07/…
goodeye
0

So listen Sie alle eindeutigen Erweiterungen von cmd unter dem Pfad auf, den Sie gerade verwenden:

Powershell -Command "Get-ChildItem . -Include *.* -Recurse | Select-Object Extension | Sort-Object -Property Extension -Unique"
Kofifus
quelle
0

Ich fand es nützlich, mich zu ändern

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

zu

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

und zu ändern

echo %extlist::=!LF!%

zu

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

Die generierte Datei enthielt (keine Zeilenvorschübe, aber egal) .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

das konnte ich dann für mein projekt nutzen.

Steev43230
quelle