Elenca i file in modo ricorsivo mostrando solo il percorso completo e la dimensione del file dal prompt dei comandi di Windows


51

Sto provando a generare un file di testo contenente il nome file (incluso il percorso completo) e la dimensione del file per tutti i file in una directory particolare e una qualsiasi delle sue sottodirectory (ovvero ricorsivamente). Idealmente, non voglio virgole nella dimensione del file (ma mi accontenterò di loro!)

Il seguente comando lo fa ma senza le dimensioni del file:

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

Un esempio di output sarebbe simile 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

Non penso che questo sia possibile usando dirda solo, anche se mi piacerebbe essere smentito. C'è un altro modo per farlo, usando solo i comandi disponibili dal Prompt dei comandi?

Risposte:


28

Questo dovrebbe farlo:

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

Non è molto efficiente ... eseguirlo per cartelle contenenti una tonnellata di file potrebbe essere impreciso, quindi provalo prima su piccole cartelle.

Dal "per /?" testo di aiuto (ho usato 'a' invece di '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

6
Ho usato un piccolo inconveniente usando questo: i file con spazi nel nome del file non sono stati registrati correttamente. Per risolvere questo ho aggiunto una "tokens=*"come segue@echo off & for /f "tokens=*" %a in ('dir /s /b') do echo %~fa %~za
Don Vince,

Come stamparlo su un txtfile?
Saeed Neamati,

3
Dovrebbe esserefor /r %a in (*) do echo %~fa %~za
ZAB,

1
@Saeed Neamati - Ecco un esempio >> C:\Temp\VideoList.txt- I risultati di qualsiasi processo precedente sono stati scritti in un file di testo chiamato VideoList . L'uso di uno > sovrascriverà il file ( se esiste già ) e l'uso >> aggiungerà nuovi risultati alla fine se il file di testo ( se esiste già ). Se il file di testo non esiste ancora, questo comando scrive un nuovo file con il nome specificato.
user23715

questo mi ha dato un elenco di file * .dwg, senza le dimensioni del file, in un file di testo:@echo off & for /f "tokens=*" %a in ('dir *.dwg /s /b') do echo %~fa >>dwgfiles.txt
Bloke CAD

15

Alternativa # 1: FOR / R è più intuitiva di # 2 per me.
Alternativa n. 2: FOR / F risolve il problema con "spazi nei nomi" nel suggerimento di BrianAdkins.
Alternativa n. 3: FORFILES sarebbe la mia scelta, tranne per il fatto che il percorso è tra virgolette doppie.

Brian o altri guru potrebbero avere una soluzione più elegante o essere in grado di suggerire una dozzina di altre soluzioni, ma questi tre funzionano. Ho provato a usare FOR TOKENS ma poi ho dovuto rimuovere le intestazioni e i piè di pagina, quindi sono tornato al numero 1. Ho anche pensato di creare un piccolo file .bat e chiamarlo, ma che aggiunge un altro file (anche se fornisce una maggiore flessibilità, come farebbe una funzione).

Ho testato tutte le alternative con directory e nomi di file con spazi incorporati, un nome di file di oltre 200 caratteri, un nome di file senza estensione e su root di una piccola unità (solo per tempo; un po 'lento - proprio come Brian ha suggerito - ma poi così sta effettuando la ricerca in Esplora risorse, ecco perché ho installato l'app di ricerca Tutto).

Alternativa n. 1: FOR / R

Il migliore (?) Nel tentativo di capire perché la soluzione di Brian non ha funzionato per me, ho cercato HELP FOR e ho deciso di provare l'approccio / R. (La creazione di un file sarebbe la stessa dell'alternativa n. 2).

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

Esempio: funziona (directory diversa da quella sopra per dimostrare la ricorsione)

@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

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

Una risposta corretta è:

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

Una risposta più completa con le directory soppresse e l'output (aggiunto) a un file è:

@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 = *" specifica un carattere non consentito nei nomi di file.
Nota: il secondo comando elimina anche le directory tramite / a: -d.
Nota: rendere il nome della variabile FOR in maiuscolo per chiarire la distinzione tra parametri variabili e parametri variabili se qualcuno sceglie nomi variabili diversi.
Nota: aggiunto al file solo per i sorrisi quando l'OP ha richiesto l'output in un file.

Suppongo che dovrei davvero controllare lo stato di ECHO e ripristinarlo pure.

Problema - Spazi nei nomi

La soluzione proposta da Brian non gestisce i nomi di file e cartelle contenenti spazi (almeno non nella mia configurazione di Vista).

Esempio: errato (senza delim; include la soppressione della directory per OP ma con dimensioni sia prima che dopo il nome del file per enfasi)

Nome e dimensioni troncati (4 di 6 file errati):

@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

Esempio - Corretto (nota l'output sullo schermo, non aggiunto al file)

@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 (numero di preventivo)

Questa soluzione è direttamente dagli ultimi due esempi nella documentazione FORFILES ( forfiles /?).

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

Combinando questi esempi e scrivendo in un file si ottiene la risposta (quasi):

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

Si noti che il percorso è tra virgolette nell'output.
Non importa se è attivato echo ono echo offdisattivato.
L'aggiunta di una riga vuota che separa ciascuna directory sarebbe un'estensione banale dell'IF.

Attenzione : l'uso della maschera/m *.*non restituirà i file senza estensione (come l'ultimo file nell'esempio)!

A parte : questo scrive un file in ogni directory con il contenuto di quella directory:
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize >>ForfilesSubOut.txt"non quello che l'OP voleva ma a volte utile.

Esempio: funziona (ma con il percorso completo tra virgolette)

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

Questo esempio include una directory aggiuntiva con un nome file molto lungo e un nome file senza estensione.

Problema: percorso tra virgolette

Quindi, c'è un modo semplice per rimuovere le virgolette indesiderate (?) Per l'esempio OP e salvare l'alternativa n. 3: FORFILES. (Domanda retorica: le virgolette sono una caratteristica o un difetto?)


1

Mi rendo conto che questo richiede un'utilità extra , ma puoi ottenerlo in modo abbastanza succinto usando l' utilità sfk :

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

sfk fromclip > C:\_temp\sfk_list_output.txt

(Ho ottenuto l'approccio usando il comando sfk concatenando qui )


1
powershell "dir | select name,length"

Ciò potrebbe tradire la domanda dei PO. Tuttavia, la domanda non è più rilevante sui moderni sistemi basati su Windows. L'alias Dir è stato utilizzato per aiutare a disegnare il collegamento logico.


2
Ho provato questo (Windows 7). L'esecuzione ha richiesto oltre 30 secondi (su una directory con 20 voci) e non è scesa nelle sottodirectory.
Scott,

Per la ricorsione, cambia in: powershell "Get-ChildItem -Recurse| select name,length"
giorgiomugnaini

0

Di seguito è riportato ciò che ho usato per individuare file video diversi che occupavano troppo spazio su un'unità di rete e scrivere i risultati in un file di testo su un PC locale.

Sto postando la mia risposta un po 'in ritardo per tre motivi. Uno, mi piacciono le risposte concise. Due, questa singola riga di script ha funzionato in più impostazioni per me, anche attraverso una rete. Tre, secondo il commento potenzialmente oscuro di Don Vince sotto la risposta di BrianAdkins, l'uso di token può aggirare i problemi dai nomi dei file con spazi all'interno.

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

Ho notato che percorsi di file / nomi di file molto lunghi (centinaia di caratteri) possono anche causare errori ma la ricerca non si bloccherà su quelli. Tuttavia, il percorso non viene esplorato completamente per i tuoi obiettivi. Una volta notato, è possibile compensare avviando più a fondo nella struttura delle cartelle per eliminare questo errore.

Questa pagina ss64 ha un'ottima presentazione dell'uso del comando dir , che elenca tutti gli switch, molte combinazioni di switch e mostra diversi esempi utili di sintassi corretta. Non è completo come le varie comunità di Stack Exchange, ma c'è una chiara chiarezza nella presentazione una volta che ti senti a tuo agio con gli script da riga di comando / batch.


0

Ho raggiunto questo con il seguente comando:

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

Il risultato:

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 Questo si basa sulla risposta di BillR (alternativa n. 1). Tuttavia nel mio caso si blocca @echo off.


0

Trovo il comando "du" piuttosto utile e funziona sia su Windows che su Unix (usato per verificare se tutti i file sono stati copiati durante il trasferimento di molti dati da un PC Windows a un server Web Linux):

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

uscite:

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

Tuttavia, ho potuto vedere correttamente solo i caratteri speciali in Notepad, non in Notepad ++ (deve essere qualcosa di codifica ANSI / UTF-8, non c'è tempo per analizzare esattamente in questo momento). Inoltre non ho trovato una soluzione per visualizzare le dimensioni dopo il nome del file. Utilizzare le opzioni "b" o "k" anziché "h" per visualizzare la dimensione in byte o kilobyte. Ho avuto qualche problema durante l'esecuzione del comando al di fuori della cartella che voglio analizzare. Quindi, sia meglio immettere il comando nella directory corretta ("C: \ your_dir" in questo esempio) e specificarlo nel comando.


-1

Ometti la b in dir / b / s / a: -D> results.txt e i risultati dovrebbero apparire come, (cioè dir / s / a: -D> results.txt):

Il volume nell'unità H è FILES Il numero di serie del volume è C9EB-112E

Directory di H: \ Files

29/09/2014 alle 23:36 PM 0 testing.txt 1 File (s) 0 byte

Directory di H: \ Video \ Action \ Comix

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


Questa non è una risposta alla domanda originale. Non produce l'output richiesto dall'OP.
DavidPostill

-1
where * /t  

Senza essere eccessivamente complicato, ciò dovrebbe produrre l'output desiderato. Darà un po 'più di quanto richiesto dall'OP, ma ho pensato che valesse la pena menzionarlo. Aggiungere l'opzione / R per specificare una directory diversa da quella corrente.


1
Prendi in considerazione l'aggiornamento e la conferma della tua risposta mentre provo e ricevi un messaggio di errore, ERROR: Invalid syntax. Value expected for '/r'quindi considera di tornare al tavolo da disegno e fornire la sintassi corretta e modificare la risposta con i dettagli corretti.
Pimp Juice IT

Considera di inserire il valore ... / R è l'opzione di directory, per impostazione predefinita la directory corrente se la lasci fuori.
someguy

"Darà un po 'di più di quanto richiesto dall'OP". Stai scherzando?  where /?dice: “Per impostazione predefinita, la ricerca viene eseguita lungo la directory corrente e nei percorsi specificati dalla variabile d'ambiente PATH . "- così il tuo where * /tcomando elenca tutti i file in C:\Windows\System32, alcune sottodirectory di C:\Program Filese ogni altra directory in PATH. Per me erano oltre 3000 linee. Ti preghiamo di considerare di modificare la tua risposta per renderla ragionevole. PS Senza  /R, non è ricorsivo.
Scott,

DOVE / R. *. * ha lavorato per me. / R. dice di cercare ricorsivamente dalla posizione specificata (in questo caso la sua directory corrente). *. * È il modello da abbinare. Quindi WHERE / R% USERPROFILE% * .docx mostrerà tutti i file di parole nella cartella dell'utente. (Devo scappare * con \ in questi commenti)
Acqua calda sanitaria
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.