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

Listuj pliki rekursywnie pokazując tylko pełną ścieżkę i rozmiar pliku z Wiersza poleceń Windows

Próbuję wygenerować plik tekstowy zawierający nazwę pliku (w tym pełną ścieżkę) i rozmiar pliku dla wszystkich plików w określonym katalogu i każdym z jego podkatalogów (tj. rekursywnie). Idealnie byłoby, gdybym nie chciał przecinków w rozmiarze pliku (ale mogę się nimi zadowolić!)

Poniższa komenda robi to, ale bez rozmiaru pliku:

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

Przykładowe wyjście wyglądałoby tak:

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

Nie sądzę, że jest to możliwe przy użyciu samego dir, chociaż bardzo chciałbym, aby udowodniono mi, że się mylę. Czy istnieje inny sposób, aby to zrobić, używając tylko poleceń dostępnych z Wiersza poleceń?

Odpowiedzi (9)

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

To powinno załatwić sprawę:

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

To nie jest bardzo wydajne… uruchomienie go dla folderów zawierających tonę plików może być pobieżne, więc spróbuj najpierw na małych folderach.

Z tekstu pomocy “for /?” (użyłem ‘a’ zamiast ‘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

Alternatywa #1: FOR /R jest dla mnie bardziej intuicyjna niż #2.
Alternatywa #2: FOR /F rozwiązuje problem ze “spacjami w nazwach” w sugestii BrianaAdkinsa.
Alternatywa #3: FORFILES byłaby moim wyborem, z wyjątkiem tego, że ścieżka jest w podwójnych cudzysłowach.

Brian lub inni guru mogą mieć bardziej eleganckie rozwiązanie lub mogą być w stanie zasugerować tuzin innych rozwiązań, ale te trzy działają. Próbowałem użyć FOR TOKENS, ale potem musiałem usunąć nagłówki i stopki, więc wróciłem do #1. Rozważałem również stworzenie małego pliku .bat i wywołanie go, ale to dodaje kolejny plik (chociaż zapewnia większą elastyczność, podobnie jak funkcja).

Przetestowałem wszystkie alternatywy z nazwami katalogów i plików z osadzonymi spacjami, nazwami plików o długości 200+ znaków, nazwami plików bez rozszerzenia i na głównym dysku (tylko dla czasu; trochę wolno - tak jak zasugerował Brian - ale tak samo jest z wyszukiwaniem w Eksploratorze Windows; dlatego zainstalowałem aplikację Everything search).

Alternatywa #1: FOR /R

Najlepsza(?) Próbując zrozumieć, dlaczego rozwiązanie Briana nie zadziałało dla mnie, spojrzałem na HELP FOR i zdecydowałem się spróbować podejścia /R. (Tworzenie pliku byłoby takie samo jak w alternatywie #2. )

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

Example - Works (inny katalog niż powyżej, aby zademonstrować rekurencję)

@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

Alternatywa #2: FOR /F

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

A poprawiona odpowiedź to:

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

A bardziej kompletna odpowiedź z wytłumionymi katalogami i wyjściem (dołączonym) do pliku to:

@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

Uwaga: “delims=” określa znak niedozwolony w nazwach plików.
Uwaga: Druga komenda również wyłącza katalogi przez /a:-d.
Uwaga: Nazwa zmiennej FOR jest pisana wielkimi literami, aby wyjaśnić różnicę między zmienną a parametrami zmiennej, jeśli ktoś wybierze inne nazwy zmiennych.
Uwaga: Dodany do pliku tylko dla żartów, ponieważ OP prosił o wyjście do pliku.

Przypuszczam, że naprawdę powinienem sprawdzić status ECHO i zresetować go również.

Problem - spacje w nazwach_

Rozwiązanie zaproponowane przez Briana nie obsługuje nazw plików i folderów zawierających spacje (przynajmniej nie na mojej konfiguracji Visty).

Przykład - Błędny(Bez delimitacji; Zawiera tłumienie katalogu na OP, ale z rozmiarem zarówno przed jak i po nazwie pliku dla podkreślenia)

Skrócona nazwa i rozmiar (4 z 6 plików niepoprawne):

@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

Example - Correct(Note output to screen, not appended to 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

Alternatywa #3: FORFILES (Quote Issue)

To rozwiązanie jest prosto z dwóch ostatnich przykładów w dokumentacji FORFILES (forfiles /?).

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

Połączenie tych przykładów i zapisanie do pliku daje odpowiedź (prawie):

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

Zauważ, że ścieżka jest w cudzysłowie na wyjściu.
Nie ma znaczenia, czy echo on czy echo off jest włączone.
Dodanie pustej linii oddzielającej każdy katalog byłoby trywialnym rozszerzeniem IF.

Caution : Użycie maski /m *.* nie zwróci plików bez rozszerzenia (jak ostatni plik w przykładzie)!

Aside : To zapisuje plik w każdym katalogu z zawartością tylko tego katalogu:
forfiles /s /c "cmd /c if @isdir==FALSE echo @path @fsize >>ForfilesSubOut.txt" Nie to co chciał OP, ale czasem się przydaje.

Przykład - Działa (ale z pełną ścieżką w cudzysłowie)

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

Ten przykład zawiera dodatkowy katalog z super długą nazwą pliku i nazwą pliku bez rozszerzenia.

Problem: Path in Quotes_

Czy istnieje zatem łatwy sposób na usunięcie niechcianych(?) cudzysłowów w przykładzie OP i zapisanie Alternative #3: FORFILES. (Pytanie retoryczne: Czy cytaty są cechą czy wadą?)

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

To może być oszustwo w stosunku do pytania OP. Jednak pytanie to nie jest już istotne w nowoczesnych systemach opartych na Windows. Alias Dir został użyty, aby pomóc w narysowaniu logicznego powiązania.

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

Zdaję sobie sprawę, że wymaga to dodatkowego narzędzia, ale można to osiągnąć w dość zwięzły sposób używając sfk utility :

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

sfk fromclip > C:\_temp\sfk_list_output.txt

(ja uzyskałem takie podejście używając sfk command chaining here )

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

Uważam, że polecenie “du” jest całkiem pomocne i działa zarówno na Windowsie jak i Uniksie (użyłem go do sprawdzenia, czy wszystkie pliki zostały skopiowane podczas przenoszenia dużej ilości danych z komputera PC z Windowsem na serwer WWW z Linuksem):

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

wyjścia:

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

Jednak znaki specjalne mogłem poprawnie zobaczyć tylko w Notepadzie, a nie w Notepad++ (musi to być jakaś rzecz związana z kodowaniem ANSI/UTF-8, nie mam teraz czasu na dokładną analizę). Nie znalazłem również rozwiązania, aby wyświetlić rozmiar po nazwie pliku. Użyj opcji “b” lub “k” zamiast “h”, aby wyświetlić rozmiar w bajtach lub kilobajtach. Miałem pewne problemy z uruchomieniem polecenia poza folderem, który chcę przeanalizować. Najlepiej więc zarówno wpisać polecenie we właściwym katalogu (“C:\u00_dir” w tym przykładzie) jak i określić go w poleceniu.

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

Poniżej przedstawiam to, czego użyłem do zlokalizowania plików wideo, które zajmowały zbyt dużo miejsca na dysku sieciowym i zapisania wyników do pliku tekstowego na lokalnym komputerze.

Zamieszczam moją własną nieco spóźnioną odpowiedź z trzech powodów. Po pierwsze, lubię zwięzłe odpowiedzi. Dwa, ta pojedyncza linia skryptu działała dla mnie w wielu ustawieniach, w tym w sieci. Trzy, na potencjalnie niejasny komentarz Dona Vince'a pod odpowiedzią BrianaAdkinsa, używanie tokenów może ominąć problemy z nazwami plików ze spacjami w nich.

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

Zauważyłem, że bardzo długie ścieżki do plików / nazwy plików (setki znaków) mogą również powodować błędy, ale wyszukiwanie nie zawiesi się na nich. Jednak ścieżka pozostaje nie w pełni zbadana dla twojego celu (celów). Po zauważeniu, można zrekompensować przez rozpoczęcie głębiej w strukturze folderów, aby wyeliminować ten błąd.

Ta strona ss64 ma bardzo dobrą prezentację użycia polecenia dir, wymieniając wszystkie przełączniki, wiele kombinacji przełączników i pokazując kilka użytecznych przykładów poprawnej składni. Nie jest to tak wyczerpujące jak różne społeczności Stack Exchange, ale jest zdecydowana jasność w prezentacji, gdy tylko poczujesz się komfortowo z linią poleceń/skryptami wsadowymi.

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

Osiągnąłem to za pomocą następującego polecenia:

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

Wynik:

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. Jest to oparte na odpowiedzi BillR (Alternatywa #1). Jednak w moim przypadku zawiesza się z @echo off.

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

Pomiń b w dir /b /s /a:-D > results.txt i wyniki powinny wyglądać tak, (tj. dir /s/a: -D > results.txt):

Volume in drive H is FILES Volume Serial Number is C9EB-112E

Directory of H:\Files

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

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

Bez nadmiernego komplikowania, to powinno dać pożądane wyjście. To da trochę więcej niż OP prosił, ale pomyślałem, że warto o tym wspomnieć. Dodaj przełącznik /R, aby określić katalog inny niż bieżący.