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

Geef een recursieve lijst van bestanden met alleen het volledige pad en de bestandsgrootte vanuit Windows Command Prompt

Ik probeer een tekstbestand te genereren met de bestandsnaam (inclusief volledig pad) en de bestandsgrootte voor alle bestanden in een bepaalde map en alle submappen daarvan (dus recursief). Idealiter wil ik geen komma’s in de bestandsgrootte (maar ik neem er genoegen mee!)

Het volgende commando doet het, maar zonder de bestandsgrootte:

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

Een voorbeelduitvoer zou er zo uitzien:

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

Ik denk niet dat dit mogelijk is met alleen dir, hoewel ik graag mijn ongelijk zou willen bewijzen. Is er een andere manier om dit te doen, door alleen commando’s te gebruiken die beschikbaar zijn vanaf de Command Prompt?

Antwoorden (9)

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

Dit zou het moeten doen:

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

Het is niet erg efficiënt…het uitvoeren ervan op mappen met heel veel bestanden kan lastig zijn, dus probeer het eerst op kleine mappen.

Uit de “for /?” helptekst (ik gebruikte ‘a’ in plaats van ‘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

Alternatief #1: FOR /R is voor mij intuïtiever dan #2.
Alternatief #2: FOR /F lost het probleem met “spaties in namen” in BrianAdkins’ suggestie op.
Alternatief #3: FORFILES zou mijn keuze zijn, behalve dat het pad tussen dubbele aanhalingstekens staat.

Brian of andere goeroes hebben misschien een elegantere oplossing of kunnen nog een dozijn andere oplossingen voorstellen, maar deze drie werken. Ik heb geprobeerd om FOR TOKENS te gebruiken maar dan moest ik kop- en voetteksten strippen dus ben ik teruggegaan naar #1. Ik heb ook overwogen om een klein .bat bestand te maken en dat aan te roepen, maar dat voegt weer een nieuw bestand toe (hoewel het wel meer flexibiliteit biedt, net als een functie).

Ik heb alle alternatieven getest met map- en bestandsnamen met spaties, een bestandsnaam van meer dan 200 tekens, een bestandsnaam zonder extensie, en op de root van een kleine schijf (gewoon voor de tijd; een beetje traag – net zoals Brian suggereerde – maar dat is zoeken in Windows Verkenner ook; daarom heb ik Alles zoeken app geïnstalleerd).

Alternatief #1: FOR /R

Beste(?) Terwijl ik probeerde uit te vinden waarom Brian’s oplossing niet werkte voor mij, keek ik naar HELP FOR en besloot de /R aanpak te proberen. (Het maken van een bestand zou hetzelfde zijn als in Alternatief #2. )

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

Example - Works (andere directory dan hierboven om recursie aan te tonen)

@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

Alternatief #2: FOR /F

BrianAdkins’ suggereerde:

Een gecorrigeerd antwoord is:

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

Een vollediger antwoord met directories onderdrukt en uitvoer (bijgevoegd) naar een bestand is:

@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

Opmerking: “delims=*” specificeert een karakter dat niet is toegestaan in bestandsnamen.
Opmerking: het 2e commando onderdrukt ook directories via /a:-d.
Opmerking: Maakte de FOR-variabelenaam hoofdletter om het onderscheid tussen variabele en variabele parameters te verduidelijken als iemand andere variabelenamen kiest.
Opmerking: Voor de grap toegevoegd aan bestand, omdat de OP vroeg om uitvoer naar een bestand.

Ik veronderstel dat ik echt de status van ECHO moet controleren en ook resetten.

Issue - Spaces in Names

Brian’s voorgestelde oplossing kan niet overweg met bestands- en mapnamen die spaties bevatten (althans niet op mijn Vista configuratie).

Exemplaar - Fout(Zonder delims; Inclusief het onderdrukken van de directory per OP maar met de grootte zowel voor als na de bestandsnaam voor de nadruk)

Afgeknotte naam en grootte (4 van 6 bestanden fout):

@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

Voorbeeld - Correct(Opmerking uitvoer naar scherm, niet toegevoegd aan bestand)

@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

Alternatief #3: FORFILES (Quote Issue)

Deze oplossing komt rechtstreeks uit de laatste twee voorbeelden in de FORFILES documentatie (@echo off & for /f %a in ('dir /s /b') do echo %~fa %~za).

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

Combineren van deze voorbeelden en schrijven naar een bestand levert (bijna) het antwoord op:

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

Merk op dat het pad tussen aanhalingstekens staat in de uitvoer.
Maakt niet uit of forfiles /? of echo on is omgedraaid.
Het toevoegen van een lege regel tussen elke directory zou een triviale uitbreiding van de IF zijn.

Caution : Het gebruik van het masker echo off zal geen bestanden zonder extensie teruggeven (zoals het laatste bestand in het voorbeeld)!

Aside : Dit schrijft een bestand in elke directory met inhoud van alleen die directory:
/m *.* Niet wat de OP wilde, maar soms handig.

Exemplaar - Werkt (maar met fullpath tussen aanhalingstekens)

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

Dit voorbeeld bevat een extra directory met een superlange bestandsnaam en een bestandsnaam zonder extensie.

Issue: Path in Quotes

Dus, is er een makkelijke manier om de ongewenste(?) aanhalingstekens te verwijderen volgens het OP voorbeeld en op te slaan Alternatief #3: FORFILES. (Retorische vraag: Zijn de aanhalingstekens een kenmerk of een fout?)

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

Dit is misschien valsspelen op de vraag van de OP. De vraag is echter niet langer relevant op moderne Windows-gebaseerde systemen. De Dir alias werd gebruikt om de logische link te helpen leggen.

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

Ik besef dat dit een extra utlity vereist, maar je kunt dit vrij beknopt bereiken met de sfk utility :

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

sfk fromclip > C:\_temp\sfk_list_output.txt

(ik heb de aanpak met sfk command chaining hier )

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

Ik vind het “du” commando erg handig en het werkt zowel op Windows als op Unix (ik gebruikte het om te controleren of alle bestanden waren gekopieerd toen ik veel gegevens van een Windows PC naar een Linux Web Server overzette):

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

outputs:

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

Echter, ik kon de speciale karakters alleen correct zien in Notepad, niet in Notepad++ (moet iets met ANSI/UTF-8 codering zijn, ik heb nu geen tijd om het precies te analyseren). Ik heb ook geen oplossing gevonden om de grootte weer te geven na de bestandsnaam. Gebruik de “b” of “k” opties in plaats van “h” om de grootte in bytes of kilobytes weer te geven. Ik had wat problemen met het uitvoeren van het commando buiten de map die ik wil analyseren. Dus het beste is om het commando in de juiste map (“C:jouw_dir” in dit voorbeeld) uit te voeren en deze in het commando te specificeren.

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

Hieronder staat wat ik gebruikte om videobestanden te lokaliseren die te veel ruimte in beslag namen op een netwerkschijf en de resultaten naar een tekstbestand op een lokale PC te schrijven.

Ik plaats mijn eigen ietwat late antwoord om drie redenen. Eén, ik hou van beknopte antwoorden. Twee, deze enkele regel script werkte in meerdere instellingen voor mij, inclusief over een netwerk. Drie, per Don Vince’s potentieel obscure opmerking onder BrianAdkins’ antwoord, kan het gebruik van tokens problemen van bestandsnamen met spaties erin omzeilen.

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

Ik heb gemerkt dat zeer lange bestandspaden/bestandsnamen (honderden karakters) ook fouten kunnen veroorzaken, maar het zoeken blijft daar niet op hangen. Het pad blijft echter niet volledig verkend voor je doel(en). Eenmaal opgemerkt, kunt u compenseren door dieper in de mappenstructuur te beginnen om deze fout te elimineren.

Deze pagina ss64 heeft een zeer goede presentatie van het gebruik van het dir commando, met een lijst van alle schakelaars, vele combinaties van schakelaars, en met een aantal bruikbare voorbeelden van de juiste syntaxis. Het is niet zo uitgebreid als de verschillende Stack Exchange gemeenschappen, maar er is een duidelijke helderheid in de presentatie als je eenmaal vertrouwd bent met command line/batch scripting.

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

Ik heb dit bereikt met het volgende commando:

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

Het resultaat:

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. Dit is gebaseerd op het antwoord van BillR (Alternatief #1). In mijn geval hangt het echter met @echo off.

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

Laat de b weg in dir /b /s /a:-D > results.txt en de resultaten zouden er zo uit moeten zien, (dus dir /s/a: -D > results.txt):

Volume in drive H is FILES Volume serienummer is C9EB-112E

Directory of H:iles

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

Directory van H:\VideoActionComix

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

Zonder al te ingewikkeld te worden, zou dit de gewenste output moeten geven. Het geeft een beetje meer dan waar de OP om vroeg, maar ik dacht dat het de moeite waard was om te vermelden. Voeg de /R optie toe om een andere directory dan current te specificeren.