Como extrair uma lista completa de tipos de extensão em um diretório?


28

Dentro de um diretório, e recursivamente dentro de seus subdiretórios, o que significa que todos os diretórios de um diretório são processados. Como faço para compilar uma lista completa de extensões exclusivas dentro do diretório?

O sistema operacional é o Windows XP com todas as atualizações atuais, mas eu posso executar o script se for capaz de dizer o que está fazendo, embora eu prefira não ter que instalar o dot-net, pois realmente não gosto disso.

Respostas:


29

Este script em lote fará isso.

@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

Salve-o como qualquer .batarquivo e execute-o com o comando batchfile(substitua o nome que desejar) para listar o diretório atual ou especifique um caminho com batchfile "path". Ele pesquisará todos os subdiretórios.

Se você deseja exportar para um arquivo, use batchfile >filename.txt(ou batchfile "path" >filename.txt).

Explicação

Tudo antes da for /f...linha apenas configura as coisas: faz com que o diretório de destino pesquise, permite expansão atrasada, o que me permite atualizar variáveis ​​no loop e define uma nova linha ( LF) que eu posso usar para uma saída mais limpa. Ah, e os %~1meios "obtêm o primeiro argumento, removendo aspas", o que impede citações dobradas - veja for /?.

O loop usa esse dir /b /s /a:-d "%target%"comando, pegando uma lista de todos os arquivos em todos os subdiretórios sob o destino.

%%~xiextrai a extensão dos caminhos completos que o dircomando retorna.

Uma extensão vazia é substituída por "FileWithNoExtension", para que você saiba que existe esse arquivo - se eu adicionei uma linha vazia, não é tão óbvio.

A lista atual inteira, se enviada por meio de um findcomando, para garantir exclusividade. A saída de texto do comando find é enviada para nul, essencialmente, um buraco negro - não queremos isso. Como sempre anexamos a :no final da lista, também devemos garantir que a consulta de pesquisa termine com um :para que não corresponda a resultados parciais - consulte os comentários.

% ERRORLEVEL% é definido pelo findcomando, um valor 0 indica que houve uma correspondência. Portanto, se não for 0, a extensão atual não está na lista até agora e deve ser adicionada.

A linha de eco basicamente gera e também substituo meus espaços reservados ( :) por novas linhas para torná-la agradável.


+1 @Bob: Resposta incrível, adicionar a explicação também foi uma grande ajuda. Apenas testei o script, revisei os resultados do teste e tudo funcionou muito bem. Mais uma vez, obrigado!
erros

1
Funcionou PERFEITAMENTE! Usei a seguinte sintaxe:batchfile "path" >filename.txt
lucaferrario 28/10

Ótimo roteiro! Mas há um pequeno bug: se a pasta contiver arquivos aaa.csse zzz.cs, a extensão .csnão será relatada pelo script.
Goozak

1
@Goozak Whoops. Corrigido agora. As maravilhas da pesquisa de texto ... tinham que garantir que a consulta de pesquisa terminasse com :para forçá-la a corresponder aos limites.
20916 Bob

19

Embora não cumpra estritamente o requisito para um script em lote, usei um script de PowerShell de linha única:

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

Você pode executá-lo a partir da linha de comando / arquivo em lote:

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

Não reivindico crédito por isso e, é claro, você precisará do Powershell instalado. Para versões mais recentes do Windows, não há como contornar isso.

Se você removê- C:\MyDirectorylo, ele será executado no diretório atual.

No final, ele produzirá um FileExtensions.txt contendo algo como o seguinte:

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

Dependendo da estrutura da pasta, você pode ocasionalmente receber erros notificando que você possui um caminho longo.

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.

Todos os subdiretórios lá também não serão analisados, mas os resultados para todo o resto ainda serão exibidos.


Obrigado, concorde que é uma resposta útil. Em uma nota não relacionada, ficou um pouco confuso como você postou apenas uma resposta única e ainda possui o selo "Fanático" por visitar o Superusuário por 100 dias consecutivos. Você tem o site marcado como favorito?
erros

O selo foi concedido em 2010, quando eu espreitei efetivamente, mas sou muito mais ativo no SO: stackoverflow.com/users/31532/dan-atkinson . :)
Dan Atkinson

4

Aqui está uma resposta detalhada usando o PowerShell (no Windows XP, você precisará instalar o PowerShell):

Ei, Equipe de Scripts! Como posso usar o Windows PowerShell para escolher as extensões de arquivo exclusivas usadas em uma coleção de arquivos?


1
Embora o PowerShell seja definitivamente muito mais fácil do que a linha de comando, ele é baseado no .NET. O que, infelizmente, vai contra "Eu preferiria não precisar instalar o dot-net".
Bob

1
+1 @RichardM: Concordo com Bob. Além disso, o código relacionado à contagem de instâncias de extensão encontradas - sem saber nada sobre o PowerShell - parece ter muita memória; ou seja, em vez de apenas manter uma contagem de todas as instâncias, acredito que crie uma matriz para armazenar instâncias duplicadas de uma extensão para cada extensão e faça uma contagem para cada matriz de extensão no final, o que para mim parece uma maneira muito estranha de contando instâncias de extensão. Estou esquecendo de algo? (Dito isto, o primeiro de uma linha PowerShell é bom, e eu ia tentar isso se eu não desgostei dotnet.)
erros

1
Isso é justo. Essa pergunta pode atrair pesquisadores mais abertos a uma solução do PowerShell. Lembre-se, uma pesquisa decente no Google também encontrará o link acima.
precisa

3
+1 para este link. erros óbvios não gostam de tudo .net, mas isso não significa que a solução acima seja a melhor solução a longo prazo para esse problema. Quanto mais idiomas, melhor eu acho.
Steve Rathbone

1
Aqui está outro link que trata da pesquisa recursiva, usando o PowerShell. robertbigec.wordpress.com/2011/01/07/...
goodeye

0

Para listar todas as extensões exclusivas do cmd no caminho em uso:

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

0

Achei útil mudar

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

para

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

e mudar

echo %extlist::=!LF!%

para

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

O arquivo gerado continha (sem feeds de linha, mas não 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

que eu pude usar no meu projeto.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.