Come estrarre un elenco completo di tipi di estensione all'interno di una directory?


28

All'interno di una directory e ricorsivamente all'interno delle sue sottodirectory, ovvero ogni directory all'interno di una directory viene elaborata, come faccio a compilare un elenco completo di estensioni univoche all'interno della directory?

Il sistema operativo è Windows XP con tutti gli aggiornamenti attuali, ma va bene eseguire script se sono in grado di dire cosa sta facendo, anche se preferirei non dover installare dot-net, dal momento che non mi piace davvero.

Risposte:


29

Questo script batch lo farà.

@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

Salvalo come qualsiasi .batfile ed eseguilo con il comando batchfile(sostituisci il nome che hai assegnato) per elencare la directory corrente o specifica un percorso con batchfile "path". Cercherà tutte le sottodirectory.

Se si desidera esportare in un file, utilizzare batchfile >filename.txt(o batchfile "path" >filename.txt).

Spiegazione

Tutto ciò che precede la for /f...riga imposta semplicemente le cose: ottiene la directory di destinazione da cercare, abilita l'espansione ritardata che mi consente di aggiornare le variabili nel ciclo e definisce una newline ( LF) che posso usare per un output più ordinato. Oh, e il %~1mezzo "ottieni il primo argomento, rimuovendo le virgolette" che impedisce le virgolette doppie - vedi for /?.

Il ciclo usa quel dir /b /s /a:-d "%target%"comando, afferrando un elenco di tutti i file in tutte le sottodirectory sotto la destinazione.

%%~xiestrae l'estensione dai percorsi completi dirrestituiti dal comando.

Un'estensione vuota viene sostituita con "FileWithNoExtension", quindi sai che esiste un file del genere: se invece aggiungessi una riga vuota, non sarebbe altrettanto ovvio.

L'intero elenco corrente, se inviato tramite un findcomando, per garantire unicità. L'output di testo del comando find viene inviato a nul, essenzialmente un buco nero - non lo vogliamo. Poiché aggiungiamo sempre :a alla fine dell'elenco, dovremmo anche assicurarci che la query di ricerca termini con un in :modo che non corrisponda ai risultati parziali - vedi commenti.

% ERRORLEVEL% è impostato dal findcomando, un valore di 0 indica che c'è stata una corrispondenza. Quindi, se non è 0, l'estensione corrente non è ancora nell'elenco e dovrebbe essere aggiunta.

La linea di eco in pratica emette e sostituisco anche i miei segnaposto ( :) con le nuove righe per renderlo piacevole.


+1 @Bob: risposta incredibile, l'aggiunta della spiegazione è stata di grande aiuto. Ho appena testato la sceneggiatura, esaminato i risultati del test e tutto ha funzionato alla grande. Grazie ancora!
errori del

1
Ha funzionato PERFETTAMENTE! Ho usato la seguente sintassi:batchfile "path" >filename.txt
lucaferrario,

Ottima sceneggiatura! Ma c'è un piccolo bug con esso: se la cartella contiene file aaa.csse zzz.cs, l'estensione .csnon verrà segnalata dallo script.
Goozak,

1
@Goozak Whoops. Riparato ora. Le meraviglie della ricerca di testo ... dovevano assicurarsi che la query di ricerca terminasse :per forzarla a corrispondere ai confini.
Bob,

19

Sebbene non soddisfi rigorosamente i requisiti per uno script batch, ho usato uno script PowerShell a riga singola:

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

Potresti potenzialmente eseguirlo dalla riga di comando / file batch:

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

Non lo rivendico e, ovviamente, avrai bisogno di Powershell installato. Per le versioni più recenti di Windows, non c'è nulla da fare.

Se lo rimuovi C:\MyDirectoryverrà eseguito nella directory corrente.

Alla fine produrrà un FileExtensions.txt contenente qualcosa di simile al seguente:

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

A seconda della struttura delle cartelle, potresti occasionalmente ricevere errori che ti informano che hai un percorso lungo.

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.

Anche le sottodirectory presenti non verranno analizzate, ma i risultati per tutto il resto verranno comunque visualizzati.


Grazie, accetta che sia una risposta utile. Su una nota non correlata, un po 'perplesso su come hai pubblicato una sola risposta, ma hai il badge "Fanatic" per visitare Superuser per 100 giorni consecutivi. Hai il sito preferito o qualcosa del genere?
errori

Il badge è stato assegnato nel 2010 quando mi sono effettivamente nascosto, ma sono molto più attivo su SO: stackoverflow.com/users/31532/dan-atkinson . :)
Dan Atkinson,

4

Ecco una risposta dettagliata usando PowerShell (con Windows XP dovrai installare PowerShell):

Ehi, Scripting Guy! Come posso utilizzare Windows PowerShell per selezionare le estensioni di file univoche utilizzate in una raccolta di file?


1
Sebbene PowerShell sia decisamente più semplice della riga di comando, si basa su .NET. Il che, sfortunatamente, va contro "Preferirei non dover installare dot-net".
Bob

1
+1 @RichardM: d'accordo con Bob. Inoltre, il codice relativo al conteggio delle istanze di estensione trovate - non conoscendo nulla di PowerShell - appare molto pesante in termini di memoria; significa invece di tenere il conto di ogni istanza, credo che creare un array per memorizzare istanze duplicate di un'estensione per ogni estensione, quindi fare un conteggio per ciascun array di estensioni alla fine, che a me sembra un modo molto strano di conteggio delle istanze di estensione. Mi sto perdendo qualcosa? (Detto questo, il primo one-liner PowerShell è carino e lo proverei se non mi piacesse il dotnet.)
errori del

1
È giusto. Questa domanda può attirare gli utenti più aperti a una soluzione PowerShell. Intendiamoci, una buona ricerca su Google troverà anche il link sopra.
RichardM

3
+1 per questo link. agli errori ovvi non piace tutto .net, ma ciò non significa che la soluzione sopra sia la migliore soluzione a lungo termine a questo problema. Più lingue meglio penso.
Steve Rathbone,

1
Ecco un altro link che affronta la ricerca ricorsiva, usando PowerShell. robertbigec.wordpress.com/2011/01/07/…
addio

0

Per elencare tutte le estensioni univoche da cmd sotto il percorso in uso:

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

0

Ho trovato utile cambiare

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

a

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

e per cambiare

echo %extlist::=!LF!%

a

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

Il file generato conteneva (nessun avanzamento riga, ma non importa) .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

che sono stato quindi in grado di utilizzare per il mio progetto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.