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

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

Sto cercando di generare un file di testo contenente il nome del file (incluso il percorso completo) e la dimensione del file per tutti i file in una particolare directory e in qualsiasi sua sotto-directory (cioè ricorsivamente). Idealmente, non voglio le virgole nella dimensione del file (ma mi accontento!)

Il seguente comando lo fa ma senza la dimensione del file:

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

Un esempio di output sarebbe come:

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 credo che questo sia possibile usando solo dir, anche se mi piacerebbe essere smentito. C'è un altro modo per farlo, usando solo i comandi che sono disponibili dal prompt dei comandi?

Risposte (9)

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

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 poco efficiente, quindi provatelo prima su cartelle piccole.

Dal testo di aiuto “for /?” (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
15
15
15
2013-10-03 23:34:41 +0000

Alternativa #1: FOR /R è più intuitiva della #2 per me.
Alternativa #2: FOR /F risolve il problema degli “spazi nei nomi” nel suggerimento di BrianAdkins.
Alternativa #3: FORFILES sarebbe la mia scelta, tranne per il fatto che il percorso è tra doppi apici.

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

Ho testato tutte le alternative con nomi di directory e di file con spazi incorporati, un nome di file di più di 200 caratteri, un nome di file senza estensione, e sulla root di un piccolo disco (solo per il tempo; un po’ lento – proprio come suggerito da Brian – ma lo è anche la ricerca in Windows Explorer; ecco perché ho installato Everything search app).

Alternativa #1: FOR /R

Best(?) Mentre cercavo di capire perché la soluzione di Brian non funzionasse per me ho guardato HELP FOR e ho deciso di provare l'approccio /R. (La creazione di un file sarebbe la stessa dell'alternativa #2. )

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

Esempio - Funziona (directory diversa dalla precedente 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 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

suggerito da BrianAdkins: @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 dei file.
Nota: il 2° comando sopprime anche le directory tramite /a:-d.
Nota: reso il nome della variabile FOR maiuscolo per chiarire la distinzione tra parametri variabili e variabili se qualcuno sceglie nomi di variabili diversi.
Nota: Aggiunto al file solo per ridere, dato che l'OP ha chiesto l'output su un file.

Suppongo che dovrei davvero controllare lo stato di ECHO e resettare anche questo.

Issue - Spaces in Names

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

Esempio - Sbagliato(Senza delimitazioni; Include la soppressione della directory per OP ma con la dimensione sia prima che dopo il nome del file per enfasi)

Nome e dimensione 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\FolderNoSpacesrd
28726032 C:\DeleteLater\FolderNoSpacesrdNoSpacesLongName.txt 28726032

Esempio - Corretto (Nota output a 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 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 (Problema di citazione)

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 su un file si ottiene la risposta (quasi):

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

Nota che il percorso è tra virgolette nell'output.
Non ha importanza se echo on o echo off è attivato.
Aggiungere una linea vuota che separa ogni directory sarebbe una banale estensione dell'IF.

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

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

Esempio - Funziona (ma con fullpath 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 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

Questo esempio include una directory extra con un nome file super lungo e un nome file senza estensione.

Percorso: Path in Quotes

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

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

Questo potrebbe essere un imbroglio sulla domanda dell'OP. Tuttavia, la domanda non è più rilevante sui moderni sistemi basati su Windows. L'alias Dir è stato usato per aiutare a disegnare il collegamento logico.

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

Mi rendo conto che questo richiede un'utilità extra_, ma si può ottenere abbastanza succintamente 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 sfk command chaining here )

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

Trovo il comando “du” abbastanza utile e funziona sia su Windows che su Unix (l'ho usato per controllare 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 i caratteri speciali solo in Notepad, non in Notepad++ (deve essere qualche cosa della codifica ANSI/UTF-8, non ho tempo di analizzare esattamente ora). Inoltre non ho trovato una soluzione per visualizzare la dimensione dopo il nome del file. Usa le opzioni “b” o “k” invece di “h” per visualizzare le dimensioni in byte o kilobyte. Ho avuto qualche problema quando ho eseguito il comando al di fuori della cartella che voglio analizzare. Quindi meglio sia inserire il comando nella giusta directory (“C:\your_dir” in questo esempio) che specificarlo nel comando.

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

Qui sotto c'è quello che ho usato per localizzare file video che occupavano troppo spazio su un'unità di rete e scrivere i risultati in un file di testo su un PC locale.

Sto pubblicando la mia risposta un po’ tardiva per tre motivi. Uno, mi piacciono le risposte concise. Due, questa singola linea 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 dei nomi dei file con spazi.

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 anche percorsi/nomi di file molto lunghi (centinaia di caratteri) possono causare errori, ma la ricerca non si blocca su quelli. Tuttavia il percorso rimane non completamente esplorato per il vostro obbiettivo. Una volta notato, puoi compensare iniziando più in profondità nella struttura delle cartelle per eliminare questo errore.

Questa pagina ss64 ha un'ottima presentazione dell'uso del comando dir, elencando tutti gli switch, molte combinazioni di switch, e mostrando diversi utili esempi di sintassi corretta. Non è così completa come le varie comunità di Stack Exchange, ma c'è una certa chiarezza nella presentazione una volta che ci si sente a proprio agio con la riga di comando/scrittura in batch.

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

Ho raggiunto questo risultato 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

P.S. Questo si basa sulla risposta di BillR (alternativa #1). Tuttavia nel mio caso si blocca con @echo off.

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

Omettere 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 nel drive H è FILES Il numero di serie del volume è C9EB-112E

Directory of H:\Files

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

Directory of H:\VideoAction\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

Senza diventare troppo complicato, questo dovrebbe produrre l'output desiderato. Darà un po’ più di quanto richiesto dall'OP, ma ho pensato che valesse la pena menzionarlo. Aggiungete lo switch /R per specificare una directory diversa da quella corrente.