Listar arquivos recursivamente mostrando apenas o caminho completo e o tamanho do arquivo no prompt de comando do Windows

51

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 (ou seja, recursivamente). Idealmente, não quero vírgulas no tamanho do arquivo (mas aceitarei elas!)

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

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

Um exemplo de saída seria semelhante a:

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 dirsozinho, embora eu adoraria provar que estou errado. Existe outra maneira de fazer isso, usando apenas comandos disponíveis no prompt de comando?

Martin Wilson
fonte

Respostas:

28

Isso deve servir:

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

Não é muito eficiente ... executá-lo para pastas que contêm uma tonelada de arquivos pode ser superficial, então tente primeiro em pequenas pastas.

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

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
Brian Adkins
fonte
6
Eu bati um pequeno obstáculo usando isso: arquivos com espaços no nome do arquivo não foram registrados corretamente. Para corrigir isso, adicionei o "tokens=*"seguinte@echo off & for /f "tokens=*" %a in ('dir /s /b') do echo %~fa %~za
Don Vince
Como imprimi-lo em um txtarquivo?
Saeed Neamati
3
Deveria serfor /r %a in (*) do echo %~fa %~za
ZAB
11
@ Saeed Neamati - Aqui está um exemplo >> C:\Temp\VideoList.txt- Os resultados de qualquer processo anterior foram gravados em um arquivo de texto chamado VideoList . Usar um > substituirá o arquivo ( se ele já existir ) e usar >> acrescentará novos resultados ao final se o arquivo de texto ( se ele já existir ). Se o arquivo de texto ainda não existir, este comando gravará um novo arquivo com o nome especificado.
user23715
isso me deu uma lista de arquivos * .dwg, sem o tamanho do arquivo, para um arquivo de texto:@echo off & for /f "tokens=*" %a in ('dir *.dwg /s /b') do echo %~fa >>dwgfiles.txt
CAD bloke
15

Alternativa nº 1: FOR / R é mais intuitivo que o nº 2 para mim.
Alternativa 2: FOR / F corrige o problema com "espaços em nomes" na sugestão de 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 sugerir uma dúzia de outras soluções, mas essas três funcionam. Tentei usar o FOR TOKENS, mas tive que retirar cabeçalhos e rodapés, então voltei para o # 1. Também considerei criar um pequeno arquivo .bat e chamá-lo, mas isso adiciona outro arquivo (embora ele forneça maior flexibilidade, como seria uma função).

Testei todas as alternativas com nomes de diretório e arquivos com espaços incorporados, um nome de arquivo com mais de 200 caracteres, um nome de arquivo sem extensão e na raiz de uma pequena unidade (apenas por tempo; um pouco lenta - como Brian sugeriu - mas então está pesquisando no Windows Explorer; foi por isso que instalei o aplicativo de pesquisa Tudo).

Alternativa 1: FOR / R

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

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

Exemplo - Trabalhos (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 Spaces\2nd Name with Spaces.txt 5805492
c:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt 3870322
c:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt 27874695
c:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.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 os diretórios suprimidos e a saída (anexada) em 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 nos nomes de arquivos.
Nota: O segundo comando também suprime os diretórios via / a: -d.
Nota: Coloque o nome da variável FOR em maiúsculas para esclarecer a distinção entre parâmetros de variável e variável se alguém escolher nomes de variáveis ​​diferentes.
Nota: Anexado ao arquivo apenas para sorrisos, pois o OP solicitava saída para um arquivo.

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

Edição - Espaços em Nomes

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

Exemplo - Errado (sem delimitações; inclui suprimir o 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\FolderNoSpaces\3rd
28726032 C:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032

Exemplo - Correto (Anote a saída na 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 Spaces\2nd Name with Spaces.txt 5805492
C:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt 3870322
C:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt 27874695
C:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.txt 28726032

Alternativa nº 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"

A combinação desses exemplos e a gravação 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 é alternado echo onou não echo off.
Adicionar uma linha em branco que separa cada diretório seria uma extensão trivial do FI.

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

Além : Escreve 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 útil.

Exemplo - Funciona (mas com 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 Spaces\2nd Name with Spaces.txt" 5805492
"c:\DeleteLater\Folder with Spaces\2ndNoSpacesLongName.txt" 3870322
"c:\DeleteLater\FolderNoSpaces\3rd Name with Spaces.txt" 27874695
"c:\DeleteLater\FolderNoSpaces\3rdNoSpacesLongName.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 entre aspas

Portanto, existe uma maneira fácil de remover as aspas indesejadas (?) Pelo exemplo do OP e salvar a Alternativa nº 3: FORFILES. (Pergunta retórica: as aspas são um recurso ou uma falha?)

BillR
fonte
1

Sei que isso requer uma utilidade extra , mas você pode conseguir isso de maneira 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 consegui a abordagem usando o comando sfk encadeado aqui )

rogersillito
fonte
1
powershell "dir | select name,length"

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

someguy
fonte
2
Eu tentei isso (Windows 7). Demorou mais de 30 segundos para ser executado (em um diretório com 20 entradas) e não desceu em subdiretórios.
Scott
Para ter recursão, altere para: powershell "Get-ChildItem -Recurse| select name,length"
giorgiomugnaini
0

Abaixo está o que eu usei para localizar arquivos de vídeo variados 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 um tanto tardia por três razões. Um, eu gosto de respostas concisas. Segundo, essa única linha de script funcionou em várias configurações para mim, inclusive em uma rede. Terceiro, pelo comentário potencialmente obscuro de Don Vince sob a resposta de BrianAdkins, o uso de tokens pode ignorar 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 caminhos de arquivos / nomes de arquivos muito longos (centenas de caracteres) também podem causar erros, mas a pesquisa não será interrompida. No entanto, o caminho ainda não foi totalmente explorado para o (s) seu (s) alvo (s). Uma vez observado, você pode compensar iniciando mais profundamente na estrutura da pasta para eliminar esse erro.

Esta página ss64 tem uma apresentação muito boa do uso do comando dir , listando todas as opções, muitas combinações de opções e mostrando vários exemplos úteis de sintaxe adequada. Não é tão abrangente quanto as várias comunidades do Stack Exchange, mas há uma clareza definitiva na apresentação quando você se sentir confortável com a linha de comando / script em lote.

user23715
fonte
0

Eu cheguei a 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

PS Isso é baseado na resposta do BillR (alternativa nº 1). No entanto, no meu caso, ele trava com @echo off.

natasha
fonte
0

Acho o comando "du" bastante útil e funciona no Windows e no Unix (usei 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, só consegui ver corretamente os caracteres especiais no bloco de notas, não no bloco de notas ++ (deve haver 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. Tive algum problema ao executar o comando fora da pasta que desejo analisar. Portanto, é melhor inserir o comando no diretório certo ("C: \ your_dir" neste exemplo) e especificá-lo no comando

Matthias Luh
fonte
-1

Omita eb em dir / b / s / a: -D> results.txt e os resultados devem ter a aparência (ou seja, dir / s / a: -D> results.txt):

O volume na unidade H é ARQUIVOS O número de série do volume é C9EB-112E

Diretório de H: \ Arquivos

29/09/2014 23:36 0 testing.txt 1 arquivo (s) 0 bytes

Diretório de H: \ Video \ Action \ Comix

06/10/2012 09:51 184.740 file1.txt 20/07/2012 06:21
864.832 file2.txt 31/08/2009 08:47 PM 606.638 file3.txt 31/08/2009 21:07 160.320 file4 .TXT

xyln
fonte
Esta não é uma resposta para a pergunta original. Não produz a saída solicitada pelo OP.
DavidPostill
-1
where * /t  

Sem ficar muito complicado, isso deve produzir a saída desejada. Vai dar um pouco mais do que o OP pediu, mas achei que valeria a pena mencionar. Adicione a opção / R para especificar um diretório que não seja atual.

someguy
fonte
11
Considere atualizar e confirmar que sua resposta funciona como eu tentei e receba uma mensagem de erro; ERROR: Invalid syntax. Value expected for '/r'portanto, volte para a prancheta e forneça a sintaxe correta e edite sua resposta com os detalhes corretos.
Pimp Juice IT
Considere inserir o valor ... / R é a opção de diretório, o padrão é o diretório atual, se você o deixar de fora.
someguy 23/03
"Vai dar um pouco mais do que o OP pediu". Você está de brincadeira?  where /?diz: “Por padrão, a pesquisa é feita no diretório atual e nos caminhos especificados pela variável de ambiente PATH . ”- então seu where * /tcomando lista todos os arquivos C:\Windows\System32, subdiretórios C:\Program Filese todos os outros diretórios PATH. Para mim, foram mais de 3000 linhas. Considere editar sua resposta para torná-la razoável. PS Sem  /R, não é recursivo.
Scott
ONDE / R. *. * trabalhou para mim. / R. diz para pesquisar recursivamente a partir do local especificado (neste caso, o diretório atual). O *. * É o padrão a ser correspondido. Portanto, WHERE / R% USERPROFILE% * .docx mostrará todos os arquivos de palavras na pasta do usuário. (Tem que escapar * com \ nestes comentários)
AQS