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

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

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 vou me contentar com 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

Não acho que isso seja possível usando dirsozinho, embora eu adorasse provar que estou errado. Existe outra maneira de fazer isso, usando apenas comandos disponíveis no prompt de comando?

Responder1

Isso deve servir:

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

Não é muito eficiente... executá-lo em pastas contendo muitos arquivos pode ser incompleto, então experimente primeiro em pastas pequenas.

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

Responder2

Alternativa nº 1: FOR /R é mais intuitivo que o nº 2 para mim.
Alternativa nº 2: FOR /F corrige o problema com "espaços nos nomes" na sugestão de BrianAdkins.
Alternativa nº 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 FOR TOKENS, mas tive que remover cabeçalhos e rodapés, então voltei para o número 1. Também considerei criar um pequeno arquivo .bat e chamá-lo, mas isso adiciona outro arquivo (embora forneça maior flexibilidade, assim como uma função).

Testei todas as alternativas com nomes de diretórios 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 unidade pequena (só para dar tempo; um pouco lento - assim como Brian sugeriu - mas então está pesquisando no Windows Explorer; é por isso que instalei o aplicativo Everything search).

Alternativa nº 1: FOR /R

Melhor(?)Ao tentar descobrir por que a solução de Brian não funcionou para mim, procurei 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 - Funciona(diretório diferente do 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 nº 2: FOR /F

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

Aresposta corrigidaé:

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

Amais completoa resposta 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: Coloque o nome da variável FOR em letras maiúsculas para esclarecer a distinção entre variáveis ​​e parâmetros de variáveis ​​caso alguém escolha nomes de variáveis ​​diferentes.
Nota: Anexado ao arquivo apenas para diversão, pois o OP solicitou a saída para um arquivo.

Suponho que deveria realmente 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 delimitações; inclui supressão de 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 (Nota de 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(Problema de cotação)

Esta solução vem diretamente dos dois últimos exemplos da 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 onou echo offestá 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 do exemplo)!

Aparte: grava um arquivo em cada diretório com o conteúdo apenas 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 (?) De acordo com o exemplo do OP e salvar a Alternativa nº 3: FORFILES. (Pergunta retórica: as citações são uma característica ou uma falha?)

Responder3

Acho o comando "du" bastante útil e funciona tanto no Windows quanto no Unix (usei-o 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 Notepad, não no Notepad++ (deve ser alguma coisa de codificação ANSI/UTF-8, não há tempo para analisar exatamente agora). Além disso, 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 alguns problemas ao executar o comando fora da pasta que desejo analisar. Portanto, é melhor inserir o comando no diretório correto ("C:\your_dir" neste exemplo) e especificá-lo no comando.

Responder4

Sei que isso requer uma utilidade extra, mas você pode conseguir isso de forma bastante sucinta usando outilitário sfk:

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

sfk fromclip > C:\_temp\sfk_list_output.txt

(Eu peguei a abordagem usandoencadeamento de comandos sfk aqui)

informação relacionada