Lista plików rekurencyjnie pokazuje tylko pełną ścieżkę i rozmiar pliku z wiersza polecenia systemu Windows

50

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 dowolnym z jego podkatalogów (tj. Rekurencyjnie). Idealnie, nie chcę przecinków w rozmiarze pliku (ale zadowolę się nimi!)

Następujące polecenie to robi, ale bez rozmiaru pliku:

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

Przykładowy wynik wygląda następująco:

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 dirsamego, chociaż chciałbym, aby udowodniono, że się mylę. Czy istnieje inny sposób, aby to zrobić, używając tylko poleceń dostępnych z wiersza polecenia?

Martin Wilson
źródło

Odpowiedzi:

28

To powinno to zrobić:

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

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

Z „for /?” tekst pomocy (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
Brian Adkins
źródło
6
Uderzyłem małą przeszkodę za pomocą tego: pliki ze spacjami w nazwie pliku nie zarejestrowały się poprawnie. Aby rozwiązać ten problem I dodaje się "tokens=*"następująco@echo off & for /f "tokens=*" %a in ('dir /s /b') do echo %~fa %~za
Don Vince
Jak wydrukować go do txtpliku?
Saeed Neamati,
3
Powinno byćfor /r %a in (*) do echo %~fa %~za
ZAB,
1
@Saeed Neamati - Oto przykład >> C:\Temp\VideoList.txt- Wyniki wszystkich wcześniejszych procesów są zapisywane w pliku tekstowym o nazwie VideoList . Użycie jednego > spowoduje nadpisanie pliku ( jeśli już istnieje ), a użycie >> spowoduje dodanie nowych wyników na końcu, jeśli plik tekstowy ( jeśli już istnieje ). Jeśli plik tekstowy jeszcze nie istnieje, to polecenie zapisuje nowy plik o określonej nazwie.
user23715
dało mi to listę plików * .dwg, bez rozmiaru pliku, do pliku tekstowego:@echo off & for /f "tokens=*" %a in ('dir *.dwg /s /b') do echo %~fa >>dwgfiles.txt
CAD bloke
14

Alternatywa # 1: FOR / R jest dla mnie bardziej intuicyjna niż # 2.
Alternatywa # 2: FOR / F rozwiązuje problem z „spacjami w nazwach” w sugestii BrianaAdkinsa.
Alternatywa # 3: FORFILES będzie 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ą zaproponować 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 z powrotem do # 1. Zastanawiałem się również nad utworzeniem małego pliku .bat i wywołaniem go, ale to dodaje kolejny plik (chociaż zapewnia większą elastyczność, tak jak funkcja).

Przetestowałem wszystkie alternatywy z nazwami katalogów i plików z osadzonymi spacjami, ponad 200-znakową nazwą pliku, nazwą pliku bez rozszerzenia i na katalogu głównym małego dysku (tylko na czas; trochę wolno - jak sugerował Brian - ale potem tak szuka w Eksploratorze Windows; dlatego zainstalowałem aplikację Wszystko do wyszukiwania).

Alternatywa nr 1: FOR / R

Najlepszy (?) Próbując dowiedzieć się, dlaczego rozwiązanie Briana nie zadziałało, spojrzałem na HELP FOR i postanowiłem wypróbować podejście / R. (Utworzenie pliku byłoby takie samo jak w wariancie nr 2).

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

Przykład - działa (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 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

Alternatywa # 2: FOR / F

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

Skorygowana odpowiedź brzmi:

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

Pełniejsza odpowiedź z katalogów tłumione i wyjścia (załączony) do pliku jest:

@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: Drugie polecenie tłumi także katalogi za pomocą / a: -d.
Uwaga: Wprowadzono wielkie litery nazwy zmiennej FOR, aby wyjaśnić różnicę między zmiennymi a parametrami zmiennych, jeśli ktoś wybierze różne nazwy zmiennych.
Uwaga: Dołączany do pliku tylko z uśmiechem, gdy OP poprosił o wyjście do pliku.

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

Problem - spacje w nazwach

Proponowane rozwiązanie Briana nie obsługuje nazw plików i folderów zawierających spacje (przynajmniej nie w mojej konfiguracji Visty).

Przykład - źle (bez ograniczeń; Obejmuje blokowanie katalogu na OP, ale z rozmiarem zarówno przed jak i po nazwie pliku dla podkreślenia)

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

@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

Przykład - Prawidłowo (uwaga wyprowadzana na ekran, nie dołączana do pliku)

@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

Alternatywa # 3: FORFILES (problem z wyceną )

To rozwiązanie pochodzi bezpośrednio 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 onczy echo offjest przełączana.
Dodanie pustej linii oddzielającej każdy katalog byłoby trywialnym rozszerzeniem IF.

Uwaga : użycie maski/m *.*nie zwróci plików bez rozszerzenia (jak na przykład ostatni plik)!

Poza tym : 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, czego chciał OP, ale czasem przydatny.

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 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

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

Problem: ścieżka w cytatach

Czy istnieje prosty sposób na usunięcie niechcianych (?) Cytatów z przykładu OP i zapisanie Alternatywy # 3: FORFILES. (Pytanie retoryczne: czy cytaty są cechą czy wadą?)

BillR
źródło
1
powershell "dir | select name,length"

To może oszukiwać w kwestii PO. Pytanie to nie jest jednak istotne w nowoczesnych systemach Windows. Alias ​​Dir został użyty, aby narysować łącze logiczne.

jakiś facet
źródło
2
Próbowałem tego (Windows 7). Uruchomienie trwało ponad 30 sekund (w katalogu z 20 wpisami) i nie zstąpiło do podkatalogów.
Scott
Aby skorzystać z rekurencji, zmień na: powershell "Get-ChildItem -Recurse| select name,length"
giorgiomugnaini
0

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

Publikuję własną, nieco spóźnioną odpowiedź z trzech powodów. Po pierwsze, lubię zwięzłe odpowiedzi. Po drugie, ten jeden wiersz skryptu działał dla mnie w wielu ustawieniach, w tym w sieci. Po trzecie, według potencjalnie niejasnego komentarza Dona Vince'a pod odpowiedzią BrianaAdkinsa, użycie 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 / nazwy plików (setki znaków) mogą również powodować błędy, ale wyszukiwanie się na nich nie zawiesi. Jednak ścieżka nie jest w pełni zbadana dla celów. Po odnotowaniu można to zrekompensować, uruchamiając głębiej strukturę folderów, aby wyeliminować ten błąd.

Ta strona ss64 ma bardzo dobrą prezentację użycia polecenia dir , zawierającą listę wszystkich przełączników, wiele kombinacji przełączników oraz kilka użytecznych przykładów poprawnej składni. Nie jest tak wszechstronny, jak różne społeczności Stack Exchange, ale w prezentacji jest wyraźna, gdy tylko zaznajomisz się z wierszem poleceń / skryptami wsadowymi.

użytkownik23715
źródło
0

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

PS Jest to oparte na odpowiedzi BillR (Alternative # 1). Jednak w moim przypadku się to utrzymuje @echo off.

natasha
źródło
0

Uważam, że polecenie „du” jest bardzo pomocne i działa zarówno w systemie Windows, jak i Unix (użyłem go do sprawdzenia, czy wszystkie pliki zostały skopiowane podczas przesyłania dużej ilości danych z komputera z systemem Windows na serwer Linux w sieci Web):

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

Widziałem jednak tylko znaki specjalne w Notatniku, a nie w Notepad ++ (musi to być jakieś kodowanie ANSI / UTF-8, nie ma czasu na dokładne analizowanie w tej chwili). 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 trochę problemów podczas uruchamiania polecenia poza folderem, który chcę analizować. Dlatego najlepiej zarówno wpisać polecenie w odpowiednim katalogu (w tym przykładzie „C: \ twój_katalog”), jak i podać je w poleceniu.

Matthias Luh
źródło
-1

Pomiń b w dir / b / s / a: -D> results.txt, a wyniki powinny wyglądać następująco: (tj. Dir / s / a: -D> results.txt):

Wolumin na dysku H to PLIKI Numer seryjny woluminu to C9EB-112E

Katalog H: \ Files

09/29/2014 23:36 0 test.txt 1 Plik (i) 0 bajtów

Katalog H: \ Video \ Action \ Comix

10/06/2012 09:51 184,740 plik1.txt 07/20/2012 06:21 AM
864,832 plik2.txt 08/31/2009 08:47 PM 606 638 plik3.txt 08/31/2009 09:07 PM 160,320 plik4 .tekst

Xyln
źródło
To nie jest odpowiedź na pierwotne pytanie. Nie daje wyników, o które prosił OP.
DavidPostill
-1
where * /t  

Bez nadmiernego komplikowania powinno to zapewnić pożądaną wydajność. Daje to nieco więcej, niż wymagał PO, ale pomyślałem, że warto o tym wspomnieć. Dodaj przełącznik / R, aby określić katalog inny niż bieżący.

jakiś facet
źródło
1
Zastanów się nad aktualizacją i potwierdzeniem, że twoja odpowiedź działa, gdy próbowałem i pojawi się komunikat o błędzie, ERROR: Invalid syntax. Value expected for '/r'więc wróć do tablicy kreślarskiej i podaj poprawną składnię i edytuj swoją odpowiedź z poprawnymi szczegółami.
Pimp Juice IT
Zastanów się nad wprowadzeniem wartości ... / R jest przełącznikiem katalogu, domyślnie jest to katalog bieżący, jeśli go pominąć.
pewnego dnia
„Daje to nieco więcej, niż wymagał PO”. Żartujesz?  where /?mówi: „Domyślnie wyszukiwanie odbywa się wzdłuż bieżącego katalogu i ścieżek określonych przez zmienną środowiskową PATH . ”- więc twoje where * /tpolecenie wyświetla wszystkie pliki w C:\Windows\System32, niektóre podkatalogi C:\Program Filesi każdy inny katalog w PATH. Dla mnie było to ponad 3000 linii. Proszę rozważyć edycję swojej odpowiedzi, aby była uzasadniona. PS Bez  /R, to nie jest rekurencyjne.
Scott
GDZIE / R. *. * pracował dla mnie. / R. mówi, aby wyszukiwać rekurencyjnie z określonej lokalizacji (w tym przypadku z jej bieżącego katalogu). *. * To wzór do dopasowania. Więc GDZIE / R% USERPROFILE% * .docx pokaże wszystkie pliki słów w folderze użytkownika. (Muszą uciec * z \ w tych komentarzach)
DHW