Listet Dateien rekursiv auf und zeigt nur den vollständigen Pfad und die Dateigröße an der Windows-Eingabeaufforderung an

50

Ich versuche, eine Textdatei zu generieren, die den Dateinamen (einschließlich des vollständigen Pfads) und die Dateigröße für alle Dateien in einem bestimmten Verzeichnis und in einem seiner Unterverzeichnisse (dh rekursiv) enthält. Im Idealfall möchte ich keine Kommas in der Dateigröße (aber ich werde mich damit zufrieden geben!)

Der folgende Befehl tut es aber ohne die Dateigröße:

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

Eine Beispielausgabe würde folgendermaßen aussehen:

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

Ich denke nicht, dass dies diralleine möglich ist , obwohl ich es lieben würde, wenn ich mich als falsch erweisen würde. Gibt es eine andere Möglichkeit, dies zu tun, indem nur Befehle verwendet werden, die über die Eingabeaufforderung verfügbar sind?

Martin Wilson
quelle

Antworten:

28

Das sollte es tun:

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

Es ist nicht sehr effizient ... es für Ordner auszuführen, die eine Menge Dateien enthalten, kann lückenhaft sein. Versuchen Sie es also zuerst mit kleinen Ordnern.

Aus dem "für /?" Hilfetext (ich habe 'a' anstelle von 'I' verwendet)

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
quelle
6
Ich habe ein kleines Problem damit: Dateien mit Leerzeichen im Dateinamen wurden nicht korrekt registriert. Um dies zu beheben, fügte ich "tokens=*"Folgendes hinzu@echo off & for /f "tokens=*" %a in ('dir /s /b') do echo %~fa %~za
Don Vince
Wie drucke ich es in eine txtDatei?
Saeed Neamati
3
Es sollte seinfor /r %a in (*) do echo %~fa %~za
ZAB
1
@ Saeed Neamati - Hier ist ein Beispiel >> C:\Temp\VideoList.txt- Die Ergebnisse aller zuvor durchgeführten Prozesse werden in eine Textdatei mit dem Namen VideoList geschrieben . Mit one > wird die Datei überschrieben ( falls bereits vorhanden ) und mit >> werden neue Ergebnisse an das Ende angehängt, falls die Textdatei bereits vorhanden ist . Wenn die Textdatei noch nicht vorhanden ist, schreibt dieser Befehl eine neue Datei mit dem angegebenen Namen.
user23715
Dies gab mir eine Liste von * .dwg-Dateien ohne Dateigröße in eine Textdatei:@echo off & for /f "tokens=*" %a in ('dir *.dwg /s /b') do echo %~fa >>dwgfiles.txt
CAD-Kerl
14

Alternative Nr. 1: FOR / R ist für mich intuitiver als Nr. 2.
Alternative 2: FOR / F behebt das Problem mit "Leerzeichen in Namen" in BrianAdkins Vorschlag.
Alternative 3: FORFILES wäre meine Wahl, außer dass der Pfad in doppelten Anführungszeichen steht.

Brian oder andere Gurus haben vielleicht eine elegantere Lösung oder können vielleicht ein Dutzend anderer Lösungen vorschlagen, aber diese drei funktionieren. Ich habe versucht, FOR TOKENS zu verwenden, musste dann aber Kopf- und Fußzeilen entfernen, sodass ich wieder zu Nummer 1 zurückkehrte. Ich habe auch darüber nachgedacht, eine kleine .bat-Datei zu erstellen und sie aufzurufen, aber dadurch wird eine weitere Datei hinzugefügt (obwohl dies eine größere Flexibilität bietet als eine Funktion).

Ich habe alle Alternativen mit Verzeichnis- und Dateinamen mit eingebetteten Leerzeichen, einem Dateinamen mit mehr als 200 Zeichen, einem Dateinamen ohne Erweiterung und auf dem Stammverzeichnis eines kleinen Laufwerks getestet (nur für kurze Zeit; ein wenig langsam - genau wie Brian es vorgeschlagen hatte - aber dann so sucht im Windows Explorer, deshalb habe ich Everything search installiert.

Alternative 1: FOR / R

Am besten (?) Als ich versuchte herauszufinden, warum Brians Lösung bei mir nicht funktionierte, schaute ich auf HELP FOR und beschloss, den / R-Ansatz zu versuchen. (Das Erstellen einer Datei entspricht Alternative 2.)

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

Beispiel - Works (anderes Verzeichnis als oben, um die Rekursion zu demonstrieren)

@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

Alternative 2: FOR / F

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

Eine korrigierte Antwort lautet:

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

Eine vollständigere Antwort, bei der Verzeichnisse unterdrückt und an eine Datei angehängt werden, lautet:

@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

Hinweis: "delims = *" gibt ein Zeichen an, das in Dateinamen nicht zulässig ist.
Hinweis: Der zweite Befehl unterdrückt auch Verzeichnisse über / a: -d.
Anmerkung: Der FOR-Variablenname wurde in Großbuchstaben geschrieben, um die Unterscheidung zwischen Variablen- und Variablenparametern zu verdeutlichen, wenn jemand andere Variablennamen auswählt.
Hinweis: Wird nur zum Grinsen an die Datei angehängt, da das OP die Ausgabe in eine Datei anfordert.

Ich nehme an, ich sollte den Status von ECHO wirklich überprüfen und auch zurücksetzen.

Problem - Leerzeichen in Namen

Brians vorgeschlagene Lösung behandelt keine Datei- und Ordnernamen, die Leerzeichen enthalten (zumindest nicht in meiner Vista-Konfiguration).

Beispiel - Falsch (Ohne Trennzeichen; Beinhaltet das Unterdrücken des Verzeichnisses pro OP, jedoch mit der Größe vor und nach dem Dateinamen zur Hervorhebung)

Verkürzter Name und Größe (4 von 6 Dateien falsch):

@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

Beispiel - Korrigieren (Ausgabe auf dem Bildschirm notieren, nicht an die Datei angehängt)

@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

Alternative 3: FORFILES ( Angebotsausgabe )

Diese Lösung stammt direkt aus den letzten beiden Beispielen in der FORFILES-Dokumentation ( forfiles /?).

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

Wenn Sie diese Beispiele kombinieren und in eine Datei schreiben, erhalten Sie (fast) die Antwort:

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

Beachten Sie, dass der Pfad in der Ausgabe in Anführungszeichen steht.
Egal ob umgeschaltet echo onoder echo off.
Das Hinzufügen einer Leerzeile, die jedes Verzeichnis trennt, wäre eine triviale Erweiterung der IF.

Achtung : Bei Verwendung der Maske/m *.*werden keine Dateien ohne Erweiterung zurückgegeben (wie die letzte Datei im Beispiel)!

Nebenbei : Dies schreibt eine Datei in jedes Verzeichnis mit dem Inhalt nur dieses Verzeichnisses:
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize >>ForfilesSubOut.txt"Nicht das, was das OP wollte, aber manchmal praktisch.

Beispiel - Funktioniert (jedoch mit vollständigem Pfad in Anführungszeichen)

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

Dieses Beispiel enthält ein zusätzliches Verzeichnis mit einem sehr langen Dateinamen und einem Dateinamen ohne Erweiterung.

Problem: Pfad in Anführungszeichen

Gibt es eine einfache Möglichkeit, die unerwünschten (?) Anführungszeichen gemäß dem OP-Beispiel zu entfernen und Alternative 3: FORFILES zu speichern? (Rhetorische Frage: Sind die Zitate ein Merkmal oder ein Fehler?)

BillR
quelle
1

Ich weiß , dass dies ein zusätzliches Dienstprogramm erfordert , aber Sie können dies mit dem Dienstprogramm sfk ziemlich genau erreichen :

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

sfk fromclip > C:\_temp\sfk_list_output.txt

(Ich habe den Ansatz mit sfk Befehl Verkettung hier )

Rogersillito
quelle
1
powershell "dir | select name,length"

Dies kann ein Betrug in der Frage des OP sein. Auf modernen Windows-basierten Systemen ist die Frage jedoch nicht mehr relevant. Der Dir-Alias ​​wurde zum Zeichnen der logischen Verknüpfung verwendet.

irgendein Typ
quelle
2
Ich habe es versucht (Windows 7). Die Ausführung dauerte über 30 Sekunden (bei einem Verzeichnis mit 20 Einträgen) und führte nicht in Unterverzeichnisse.
Scott
Um eine Rekursion zu haben, wechseln Sie bitte zu: powershell "Get-ChildItem -Recurse| select name,length"
giorgiomugnaini
0

Im Folgenden habe ich nach Videodateien gesucht, die auf einem Netzwerklaufwerk zu viel Platz beanspruchten, und die Ergebnisse in eine Textdatei auf einem lokalen PC geschrieben.

Ich poste meine eigene, etwas verspätete Antwort aus drei Gründen. Erstens mag ich prägnante Antworten. Zweitens funktionierte diese einzige Skriptzeile in mehreren Einstellungen, auch in einem Netzwerk. Drei, laut Don Vinces möglicherweise undurchsichtigem Kommentar unter BrianAdkins 'Antwort, können durch die Verwendung von Tokens Probleme durch Dateinamen mit Leerzeichen umgangen werden.

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

Mir ist aufgefallen, dass sehr lange Dateipfade / Dateinamen (Hunderte von Zeichen) ebenfalls Fehler verursachen können, aber die Suche bleibt bei diesen nicht hängen. Der Pfad ist jedoch für Ihre Ziele noch nicht vollständig erforscht. Einmal notiert, können Sie dies kompensieren, indem Sie tiefer in die Ordnerstruktur einsteigen, um diesen Fehler zu beseitigen.

Diese Seite ss64 bietet eine sehr gute Darstellung der Verwendung des Befehls dir , listet alle Schalter und viele Schalterkombinationen auf und zeigt einige nützliche Beispiele für die richtige Syntax. Es ist nicht so umfassend wie die verschiedenen Stack Exchange-Communitys, aber es gibt eine eindeutige Klarheit in der Präsentation, sobald Sie sich mit Befehlszeilen- / Batch-Skripten vertraut gemacht haben.

user23715
quelle
0

Ich habe dies mit folgendem Befehl erreicht:

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

Das Ergebnis:

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 Dies basiert auf der Antwort von BillR (Alternative # 1). Allerdings hängt es bei mir mit @echo off.

Natascha
quelle
0

Ich finde den "du" -Befehl ziemlich hilfreich und er funktioniert sowohl unter Windows als auch unter Unix (dient dazu zu überprüfen, ob alle Dateien beim Übertragen vieler Daten von einem Windows-PC auf einen Linux-Webserver kopiert wurden):

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

Ausgänge:

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

Allerdings konnte ich nur die Sonderzeichen in Notepad richtig sehen, nicht in Notepad ++ (muss eine ANSI / UTF-8-Codierungssache sein, keine Zeit, um genau zu analysieren). Außerdem habe ich keine Lösung gefunden, um die Größe nach dem Dateinamen anzuzeigen. Verwenden Sie die Optionen "b" oder "k" anstelle von "h", um die Größe in Byte oder Kilobyte anzuzeigen. Ich hatte Probleme beim Ausführen des Befehls außerhalb des Ordners, den ich analysieren möchte. Geben Sie den Befehl am besten im richtigen Verzeichnis ein (in diesem Beispiel "C: \ your_dir") und geben Sie ihn im Befehl an.

Matthias Luh
quelle
-1

Lassen Sie das b in dir / b / s / a: -D> results.txt weg und die Ergebnisse sollten so aussehen (dh dir / s / a: -D> results.txt):

Der Datenträger in Laufwerk H ist DATEIEN. Die Datenträger-Seriennummer lautet C9EB-112E

Verzeichnis von H: \ Files

29.09.2014 23:36 0 testing.txt 1 Datei (en) 0 Byte

Verzeichnis von H: \ Video \ Action \ Comix

10.06.2012 09:51 184,740 file1.txt 20.07.2012
06:21 864,832 file2.txt 31.08.2009 20:47 606,638 file3.txt 31.08.2009 21:07 160,320 file4 .TXT

xyln
quelle
Dies ist keine Antwort auf die ursprüngliche Frage. Es erzeugt nicht die Ausgabe, nach der er OP gefragt hat.
DavidPostill
-1
where * /t  

Ohne allzu kompliziert zu werden, sollte dies die gewünschte Ausgabe ergeben. Es wird ein bisschen mehr geben, als das OP verlangt, aber ich dachte, es wäre erwähnenswert. Fügen Sie die Option / R hinzu, um ein anderes als das aktuelle Verzeichnis anzugeben.

irgendein Typ
quelle
1
Denken Sie daran, Ihre Antwort so zu aktualisieren und zu bestätigen, wie ich es versucht habe, und eine Fehlermeldung zu erhalten. ERROR: Invalid syntax. Value expected for '/r'Gehen Sie zurück zum Zeichenbrett und geben Sie die richtige Syntax an und bearbeiten Sie Ihre Antwort mit den richtigen Details.
Pimp Juice IT
Überlegen Sie, ob Sie den Wert eingeben möchten ... / R ist der Verzeichnisschalter. Wenn Sie ihn weglassen, wird standardmäßig das aktuelle Verzeichnis verwendet.
Irgendwann am
"Es wird ein bisschen mehr geben, als das OP verlangt." Machst du Witze?  where /?sagt: „Standardmäßig wird die Suche entlang des aktuellen Verzeichnisses und in den von der Umgebungsvariablen PATH angegebenen Pfaden durchgeführt . ”- so where * /tlistet Ihr Befehl jede Datei in C:\Windows\System32, einige Unterverzeichnisse von C:\Program Filesund jedes andere Verzeichnis in auf PATH. Für mich waren das über 3000 Zeilen. Bitte überlegen Sie, Ihre Antwort zu bearbeiten, um sie angemessen zu gestalten. PS Ohne  /Rist es nicht rekursiv.
Scott
WO / R. *. * arbeitete für mich. / R. sagt, dass rekursiv vom angegebenen Ort gesucht werden soll (in diesem Fall vom aktuellen Verzeichnis). Das *. * Ist das passende Muster. WHERE / R% USERPROFILE% * .docx zeigt also alle Wortdateien im Ordner des Benutzers an. (Müssen * mit \ in diesen Kommentaren entkommen)
DHW