Listar arquivos de forma recursiva mostrando apenas o caminho completo e o tamanho do arquivo do Prompt de Comando do Windows

45

Estou tentando gerar um arquivo de texto contendo o nome do arquivo (incluindo o caminho completo) e o tamanho do arquivo para todos os arquivos em um diretório específico e qualquer um de seus subdiretórios (por exemplo, recursivamente). Idealmente, não quero vírgulas no tamanho do arquivo (mas vou me contentar com elas!)

O comando a seguir faz isso, mas sem o tamanho do arquivo:

dir /b /s /a:-D > results.txt

Um exemplo de saída seria parecido com:

C:\Users\Martin\Pictures\Table\original\PC120013.JPG  227298
C:\Users\Martin\Pictures\Table\original\PC120014.JPG  123234
C:\Users\Martin\Pictures\Table\original\PC120015.JPG  932344

Eu não acho que isso seja possível usando dir sozinho, embora eu adoraria estar errado. Existe outra maneira de fazer isso, usando apenas comandos que estão disponíveis no Prompt de Comando?

    
por Martin Wilson 03.10.2013 / 14:50

9 respostas

25

Isso deve ser feito:

@echo off & for /f %a in ('dir /s /b') do echo %~fa %~za

Não é muito eficiente ... executá-lo para pastas contendo uma tonelada de arquivos pode ser incompleto, então tente em pastas pequenas primeiro.

Do "para /?" texto de ajuda (usei 'a' em vez de 'eu')

In addition, substitution of FOR variable references has been enhanced.
You can now use the following optional syntax:

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file
%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string

The modifiers can be combined to get compound results:

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only
%~dp$PATH:I - searches the directories listed in the PATH
               environment variable for %I and expands to the
               drive letter and path of the first one found.
%~ftzaI     - expands %I to a DIR like output line
    
por 03.10.2013 / 15:44
13

Alternativa # 1: FOR / R é mais intuitivo que o # 2 para mim.
Alternativa # 2: FOR / F corrige o problema com "espaços em nomes" na sugestão do BrianAdkins.
Alternativa # 3: FORFILES seria minha escolha, exceto que o caminho está entre aspas duplas.

Brian ou outros gurus podem ter uma solução mais elegante ou podem sugerir uma dúzia de outras soluções, mas essas três funcionam. Eu tentei usar FOR TOKENS, mas depois tive que remover cabeçalhos e rodapés, então voltei ao # 1. Eu também considerei criar um pequeno arquivo .bat e chamá-lo, mas isso adiciona outro arquivo (embora ele forneça maior flexibilidade, assim como uma função).

Eu testei todas as alternativas com diretórios e nomes de arquivos com espaços embutidos, um nome de arquivo de 200+ caracteres, um nome de arquivo sem extensão e na raiz de uma pequena unidade (apenas por tempo; um pouco lento - como Brian sugeriu - mas então está pesquisando no Windows Explorer, é por isso que eu instalei o aplicativo Everything search).

Alternativa # 1: FOR / R

Melhor (?) Ao tentar descobrir por que a solução de Brian não funcionou para mim, olhei para o HELP FOR e decidi tentar a abordagem de / R. (Criando um arquivo seria o mesmo que na alternativa # 2.)

@echo off & for /R "c:\deletelater\folder with spaces" %A in (*.*) do echo %~fA %~zA

Exemplo - Works (diretório diferente do que acima para demonstrar recursão)

@echo off & for /R "c:\deletelater" %A in (*.*) do echo %~fA %~zA
c:\DeleteLater\Name with Spaces.txt 19800676
c:\DeleteLater\NoSpacesLongName.txt 21745440
c:\DeleteLater\Folder with Spacesnd Name with Spaces.txt 5805492
c:\DeleteLater\Folder with SpacesndNoSpacesLongName.txt 3870322
c:\DeleteLater\FolderNoSpacesrd Name with Spaces.txt 27874695
c:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt 28726032

Alternativa # 2: FOR / F

BrianAdkins sugeriu: @echo off & for /f %a in ('dir /s /b') do echo %~fa %~za

Uma resposta corrigida é:

@echo off & for /f "delims=*" %A in ('dir /s /b') do echo %~fA %~zA 

Uma resposta mais completa com diretórios suprimidos e saída (anexada) a um arquivo é:

@echo Results on %DATE% for %CD% >> YourDirFile.txt & echo off & for /f "delims=*" %A in ('dir /s /b /a:-d') do echo %~fA %~zA >> YourDirFile.txt

Nota: "delims = *" especifica um caractere não permitido em nomes de arquivos.
Nota: o segundo comando também suprime diretórios via / a: -d.
Nota: Feito o nome da variável FOR maiúscula para clarificar a distinção entre variáveis e parâmetros variáveis se alguém escolher diferentes nomes de variáveis.
Nota: Anexado ao arquivo apenas para sorrisos como o OP pediu a saída para um arquivo.

Suponho que eu realmente deveria verificar o status do ECHO e redefini-lo também.

Problema - espaços em nomes

A solução proposta por Brian não lida com nomes de arquivos e pastas contendo espaços (pelo menos não na minha configuração do Vista).

Exemplo - Errado (Sem delims; inclui a supressão do diretório por OP, mas com tamanho antes e depois do nome do arquivo para ênfase)

Nome e tamanho truncados (4 de 6 arquivos incorretos):

@echo off & for /f %A in ('dir /s /b /a:-d') do echo %~zA %~fA %~zA
 C:\DeleteLater\Name
21745440 C:\DeleteLater\NoSpacesLongName.txt 21745440
 C:\DeleteLater\Folder
 C:\DeleteLater\Folder
 C:\DeleteLater\FolderNoSpacesrd
28726032 C:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt 28726032

Exemplo - Correto (Observe a saída para a tela, não anexada ao arquivo)

@echo off & for /f "delims=*" %A in ('dir /s /b /a:-d') do echo %~fA %~zA
C:\DeleteLater\Name with Spaces.txt 19800676
C:\DeleteLater\NoSpacesLongName.txt 21745440
C:\DeleteLater\Folder with Spacesnd Name with Spaces.txt 5805492
C:\DeleteLater\Folder with SpacesndNoSpacesLongName.txt 3870322
C:\DeleteLater\FolderNoSpacesrd Name with Spaces.txt 27874695
C:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt 28726032

Alternativa # 3: FORFILES (edição de cotação)

Esta solução é diretamente dos dois últimos exemplos na documentação do FORFILES ( forfiles /? ).

FORFILES /S /M *.doc /C "cmd /c echo @fsize"
FORFILES /M *.txt /C "cmd /c if @isdir==FALSE notepad.exe @file"

Combinar esses exemplos e gravar em um arquivo produz a resposta (quase):

forfiles /s  /c "cmd /c if @isdir==FALSE echo @path @fsize" >>ForfilesOut.txt

Observe que o caminho está entre aspas na saída.
Não importa se echo on ou echo off é alternado.
Adicionar uma linha em branco separando cada diretório seria uma extensão trivial do IF.

Cuidado : Usar a máscara /m *.* não retornará arquivos sem extensão (como o último arquivo no exemplo)!

> Aside : Isso grava um arquivo em cada diretório com o conteúdo desse diretório:
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize >>ForfilesSubOut.txt" Não é o que o OP queria, mas às vezes é prático.

Exemplo - Funciona (mas com o caminho completo entre aspas)

forfiles /s  /c "cmd /c if @isdir==FALSE echo @path @fsize"

"c:\DeleteLater\Name with Spaces.txt" 19800676
"c:\DeleteLater\NoSpacesLongName.txt" 21745440
"c:\DeleteLater\Folder with Spacesnd Name with Spaces.txt" 5805492
"c:\DeleteLater\Folder with SpacesndNoSpacesLongName.txt" 3870322
"c:\DeleteLater\FolderNoSpacesrd Name with Spaces.txt" 27874695
"c:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt" 28726032
"c:\DeleteLater\MoreFiles\A really really long file name that goes on and on 123456789 asdfghjkl zxcvnm qwertyuiop and still A really really long file name that goes on and on 123456789 qwertyuiop and still further roughly 225 characters by now.txt" 447
"c:\DeleteLater\MoreFiles\New Text Document no extension" 0

Este exemplo inclui um diretório extra com um nome de arquivo super longo e um nome de arquivo sem extensão.

Problema: caminho nas cotações

Portanto, existe uma maneira fácil de remover as cotações indesejadas (?) pelo exemplo do OP e salvar a Alternativa # 3: FORFILES. (Pergunta retórica: as citações são uma característica ou uma falha?)

    
por 04.10.2013 / 01:34
1

Eu percebo que isso requer uma utilidade extra , mas você pode conseguir isso de forma bastante sucinta usando o utilitário sfk :

sfk cwd +run -yes "sfk list -size -tab $qfile +toclip"

sfk fromclip > C:\_temp\sfk_list_output.txt

(Eu tenho a abordagem usando o comando sfk encadeando aqui )

    
por 12.02.2014 / 13:47
0

Abaixo está o que eu usei para localizar vários arquivos de vídeo que estavam ocupando muito espaço em uma unidade de rede e gravar os resultados em um arquivo de texto em um PC local.

Estou postando minha própria resposta atrasada por três razões. Um, eu gosto de respostas concisas. Dois, essa linha única de script funcionou em várias configurações para mim, inclusive em uma rede. Três, por comentário potencialmente obscuro de Don Vince sob a resposta do BrianAdkins, usar tokens pode contornar problemas de nomes de arquivos com espaços neles.

for /f "tokens=*" %%a in ('dir H:\*.mov H:\*.avi H:\*.wmv H:\*.mp4 /s /b') do echo %%~fa %%~za >> C:\Temp\VideoList.txt

Percebi que os caminhos de arquivos / nomes de arquivo muito longos (centenas de caracteres) também podem causar erros, mas a pesquisa não fica suspensa neles. No entanto, o caminho permanece não totalmente explorado para seu (s) alvo (s). Uma vez observado, você pode compensar iniciando mais profundamente na estrutura de pastas para eliminar esse erro.

Esta página ss64 tem uma apresentação muito boa do uso do comando dir , listando todos os comutadores, muitas combinações de comutadores e mostrando vários exemplos úteis de sintaxe apropriada. Não é tão abrangente quanto as várias comunidades do Stack Exchange, mas há uma clara clareza na apresentação quando você se familiariza com a linha de comando / scripts em lote.

    
por 14.07.2016 / 02:19
0

Eu consegui isso com o seguinte comando:

(for /R "\path\to\directory\" %A in (*.*) do echo %~fA %~zA) | findstr /v "echo"

O resultado:

D:\Users\Natasha>(for /R ".\" %A in (*.*) do echo %~fA %~zA) | findstr /v "echo"


D:\Users\Natasha\Flowers_ (12).jpg 118886

D:\Users\Natasha\SomeFolder\data.txt 1241

D:\Users\Natasha\SomeFolder\CS\Counter-Strike_1.6.exe 272645624

P.S. Isto é baseado na resposta de BillR (Alternativa # 1). No entanto, no meu caso, trava com @echo off .

    
por 12.01.2017 / 14:48
0

Acho o comando "du" bastante útil e funciona tanto no Windows quanto no Unix (usado para verificar se todos os arquivos foram copiados ao transferir muitos dados de um PC com Windows para um servidor Web Linux):

du -ah "C:\your_dir" > "C:\file_list.txt"

saídas:

15  C:\your_dir/.htaccess
608 C:\your_dir/folder/hello.txt
1.0 C:\your_dir/folder/subfolder/test.txt
1.0 C:\your_dir/folder/subfolder
1.2M    C:\your_dir/folder/world.txt
1.2M    C:\your_dir/folder
9.0 C:\your_dir/no_file_ending
11  C:\your_dir/sample document 1.txt
684K    C:\your_dir/sample document 2 - äöüßÄÖÜáà.txt
1.9M    C:\your_dir

No entanto, eu só podia ver corretamente os caracteres especiais no Bloco de Notas, não no Notepad ++ (deve ser alguma coisa de codificação ANSI / UTF-8, não há tempo para analisar exatamente agora). Também não encontrei uma solução para exibir o tamanho após o nome do arquivo. Use as opções "b" ou "k" em vez de "h" para exibir o tamanho em bytes ou kilobytes. Eu tive alguns problemas ao executar o comando fora da pasta que eu quero analisar. Então, é melhor inserir o comando no diretório correto ("C: \ your_dir" neste exemplo) e especificá-lo no comando.

    
por 11.11.2017 / 18:59
0
powershell "dir | select name,length"

Isso pode estar traindo a questão dos OPs. No entanto, a questão não é mais relevante em sistemas modernos baseados no Windows. O alias Dir foi usado para ajudar a desenhar o link lógico.

    
por 23.03.2018 / 19:47
-1

Omitir b em dir / b / s / a: -D > results.txt e os resultados devem ser semelhantes, (por exemplo, dir / s / a: -D > results.txt):

Volume in drive H is FILES Volume Serial Number is C9EB-112E

Directory of H:\Files

09/29/2014 11:36 PM 0 testing.txt 1 File(s) 0 bytes

Directory of H:\Video\Action\Comix

10/06/2012 09:51 AM 184,740 file1.txt 07/20/2012 06:21 AM
864,832 file2.txt 08/31/2009 08:47 PM 606,638 file3.txt 08/31/2009 09:07 PM 160,320 file4.txt

    
por 30.09.2014 / 05:41
-1
where * /t  

Sem ficar excessivamente complicado, isso deve produzir o resultado desejado. Vai dar um pouco mais do que o OP pediu, mas achei que valeu a pena mencionar. Adicione a opção / R para especificar um diretório diferente do atual.

    
por 22.03.2018 / 21:22