2013-10-03 12:50:47 +0000 2013-10-03 12:50:47 +0000
53
53

Listar recursivamente ficheiros mostrando apenas o caminho completo e o tamanho do ficheiro a partir do Prompt de Comando do Windows

Estou a tentar gerar um ficheiro de texto contendo o nome do ficheiro (incluindo o caminho completo) e o tamanho do ficheiro para todos os ficheiros de um determinado directório e qualquer uma das suas subdirectorias (ou seja, recursivamente). Idealmente, não quero vírgulas no tamanho do ficheiro (mas contento-me com elas!)

O seguinte comando fá-lo mas sem o tamanho do ficheiro:

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

Um exemplo de saída pareceria:

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 creio que isto seja possível usando dir sozinho, embora gostasse de ser provado que estou errado. Haverá outra forma de o fazer, utilizando apenas comandos que estão disponíveis no Prompt de Comando?

Respostas (9)

28
28
28
2013-10-03 13:44:16 +0000

Isto deve ser suficiente:

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

Não é muito eficiente…corrê-lo para pastas contendo uma tonelada de ficheiros pode ser esquemático, por isso experimente-o primeiro em pastas pequenas.

Do texto de ajuda “para /?” (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
15
15
15
2013-10-03 23:34:41 +0000

Alternativa #1: FOR /R é mais intuitiva do que #2 para mim.
Alternativa #2: FOR /F resolve o problema com “espaços nos nomes” na sugestão de BrianAdkins.
Alternativa #3: FORFILES seria a minha escolha, excepto que o caminho está entre aspas duplas.

Brian ou outros gurus podem ter uma solução mais elegante ou podem ser capazes de sugerir uma dúzia de outras soluções, mas estas três funcionam. Tentei usar FOR TOKENS mas depois tive de desnudar cabeçalhos e rodapés, por isso voltei a ser o número 1. Também considerei criar um pequeno ficheiro .bat e chamá-lo, mas isso acrescenta outro ficheiro (embora proporcione uma maior flexibilidade, como seria uma função).

Testei todas as alternativas com directório e nomes de ficheiros com espaços incorporados, um nome de ficheiro com mais de 200 caracteres, um nome de ficheiro sem extensão, e na raiz de uma pequena unidade (apenas pelo tempo; um pouco lento – tal como Brian sugeriu – mas depois também é pesquisar no Explorador do Windows; foi por isso que instalei a aplicação de pesquisa Everything search).

Alternativo #1: FOR /R

Best(?) Enquanto tentava descobrir porque é que a solução de Brian não funcionava para mim, olhei para HELP FOR e decidi tentar a abordagem /R. (Criar um ficheiro seria o mesmo que em Alternativa #2. )

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

Exemplo - Trabalhos (directório diferente do acima para demonstrar a recorrência)

@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

Alternativo #2: PARA /F

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

A resposta corrigida* é:

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

A resposta mais completa com directórios suprimidos e a saída (anexada) a um ficheiro é:

@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

A

@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

Nota: “delims=*” especifica um carácter não permitido em nomes de ficheiros.
Nota: O 2º comando também suprime directórios via /a:-d.
Nota: Fez 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 ficheiro apenas para grins, uma vez que o OP pediu a saída para um ficheiro.

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

Issue - Espaços em Nomes

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

Exemplo - Errado(Sem delimitações; Inclui supressão de directório por OP mas com tamanho tanto antes como depois do nome do ficheiro para ênfase)

Truncado Nome e Tamanho (4 de 6 ficheiros incorrectos):

@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

Exemplo - Correcto(Nota de saída ao ecrã, não anexada ao ficheiro)

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

Alternativo #3: FORFILES (Quote Issue)

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

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

Combinando estes exemplos e escrevendo num ficheiro obtém-se a resposta (quase):

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

Note-se que o caminho está entre aspas na saída.
Não importa se echo on ou echo off é alternado.
A adição de uma linha em branco separando cada directório seria uma extensão trivial do FI.

Cautela : A utilização da máscara /m *.* não devolverá ficheiros sem extensão (como o último ficheiro, por exemplo)!

Aside : Isto escreve um ficheiro em cada directório com o conteúdo apenas desse directório:
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize >>ForfilesSubOut.txt" Não é o que o OP queria, mas por vezes é útil.

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

0x1&

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

Issue: Caminho entre aspas

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

1
1
1
2018-03-23 18:47:14 +0000
powershell "dir | select name,length"

Isto pode estar a fazer batota na questão das OPs. No entanto, a questão já não é relevante nos sistemas modernos baseados em Windows. O pseudónimo Dir foi utilizado para ajudar a desenhar a ligação lógica.

1
1
1
2014-02-12 12:47:47 +0000

Compreendo que isto requer uma utlidade extra_, mas pode conseguir isto de forma bastante sucinta utilizando o sfk utility :

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

sfk fromclip > C:\_temp\sfk_list_output.txt

(consegui a abordagem usando sfk comando encadeamento aqui )

0
0
0
2017-11-11 17:59:32 +0000

Acho o comando “du” bastante útil e funciona tanto no Windows como no Unix (utilizei-o para verificar se todos os ficheiros foram copiados ao transferir muitos dados de um PC 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

Contudo, só consegui ver correctamente 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 exactamente neste momento). Também não encontrei uma solução para mostrar o tamanho após o nome do ficheiro. Utilizar 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 quero analisar. Portanto, é melhor introduzir o comando no directório certo (“C:{your}dir” neste exemplo) e especificá-lo no comando.

0
0
0
2016-07-14 00:19:25 +0000

Abaixo está o que utilizei para localizar ficheiros de vídeo diversos que ocupavam demasiado espaço numa unidade de rede e escrever os resultados num ficheiro de texto num PC local.

Estou a publicar a minha própria resposta um pouco atrasada por três razões. Primeiro, gosto de respostas concisas. Segundo, esta única linha de script funcionou em múltiplas definições para mim, incluindo através de uma rede. Três, pelo comentário potencialmente obscuro de Don Vince sob a resposta de BrianAdkins, o uso de fichas pode contornar problemas de nomes de ficheiros com espaços.

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

Notei que percursos de ficheiro muito longos/nomes de ficheiro (centenas de caracteres) também podem causar erros, mas a pesquisa não se vai pendurar naqueles. No entanto, o caminho ainda não está totalmente explorado para o(s) seu(s) alvo(s). Uma vez anotado, pode compensar, começando mais profundamente na estrutura da pasta para eliminar este erro.

Esta página ss64 tem uma apresentação muito boa do uso do comando dir*, listando todos os interruptores, muitas combinações de interruptores, e mostrando vários exemplos úteis de sintaxe adequada. Não é tão abrangente como as várias comunidades de Stack Exchange, mas há uma clareza definitiva na apresentação, uma vez que se fica confortável com a linha de comando/escrita de lote.

0
0
0
2017-01-12 13:48:02 +0000

Cheguei a este ponto 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 do BillR (Alternativa #1). No entanto, no meu caso, pende com @echo off.

-1
-1
-1
2014-09-30 03:41:04 +0000

Omitir o b em dir /b /s /a:-D > resultados.txt e os resultados devem ser parecidos, (i.e. dir /s/a: -D > resultados.txt):

Volume na unidade H é FILES Volume Serial Number é C9EB-112E

Directório de H:\Files

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

Directório de 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

-1
-1
-1
2018-03-22 20:22:09 +0000
where * /t

Sem ficar excessivamente complicado, isto deve produzir a produção desejada. Vai dar um pouco mais do que a OP pedida, mas achei que valia a pena mencionar. Adicionar o interruptor /R para especificar um directório diferente do actual.