Czy w systemie Windows można uzyskać rozmiar folderu z wiersza poleceń bez użycia narzędzi innej firmy?
Chcę uzyskać taki sam rezultat, jaki można uzyskać, klikając prawym przyciskiem myszy folder w eksploratorze Windows → właściwości.
Czy w systemie Windows można uzyskać rozmiar folderu z wiersza poleceń bez użycia narzędzi innej firmy?
Chcę uzyskać taki sam rezultat, jaki można uzyskać, klikając prawym przyciskiem myszy folder w eksploratorze Windows → właściwości.
Odpowiedzi:
Możesz po prostu rekurencyjnie dodawać rozmiary (poniżej jest plik wsadowy):
@echo off
set size=0
for /r %%x in (folder\*) do set /a size+=%%~zx
echo %size% Bytes
Jednak powoduje to kilka problemów, ponieważ cmd
jest ograniczone do 32-bitowej arytmetyki liczb całkowitych ze znakiem. Więc otrzyma rozmiary powyżej 2 GiB źle 1 . Co więcej, prawdopodobnie wiele razy policzy dowiązania symboliczne i połączenia, więc w najlepszym przypadku jest to górna granica, a nie rzeczywisty rozmiar (chociaż będziesz mieć ten problem z każdym narzędziem).
Alternatywą jest PowerShell:
Get-ChildItem -Recurse | Measure-Object -Sum Length
lub krócej:
ls -r | measure -sum Length
Jeśli chcesz, żeby było ładniej:
switch((ls -r|measure -sum Length).Sum) {
{$_ -gt 1GB} {
'{0:0.0} GiB' -f ($_/1GB)
break
}
{$_ -gt 1MB} {
'{0:0.0} MiB' -f ($_/1MB)
break
}
{$_ -gt 1KB} {
'{0:0.0} KiB' -f ($_/1KB)
break
}
default { "$_ bytes" }
}
Możesz tego użyć bezpośrednio z cmd
:
powershell -noprofile -command "ls -r|measure -sum Length"
1 Mam gdzieś częściowo ukończoną bibliotekę bignum w plikach wsadowych, która przynajmniej otrzymuje poprawne dodawanie liczb całkowitych o dowolnej precyzji. Chyba naprawdę powinienem to wypuścić :-)
du
podaje rozmiar katalogu, ale wszystko, co robi, to chodzenie po drzewie i podsumowywanie. Coś, co można bardzo elegancko wyrazić w potoku, jak tutaj :-). W przypadku PowerShell zwykle szukam sposobu, w jaki można rozłożyć cel wysokiego poziomu na odpowiednie operacje niższego poziomu.
folder\*
nie działa dla mnie rozmiar folderu, który umieściłem w miejscu, pokazuje 0 bajtów, czy jest jakieś rozwiązanie?
Jest do tego wbudowane narzędzie Windows :
dir /s 'FolderName'
Spowoduje to wydrukowanie wielu niepotrzebnych informacji, ale na końcu będzie taki rozmiar folderu:
Total Files Listed:
12468 File(s) 182,236,556 bytes
Jeśli chcesz dołączyć ukryte foldery, dodaj /a
.
Proponuję pobrać narzędzie DU z pakietu Sysinternals Suite dostarczonego przez Microsoft pod tym linkiem http://technet.microsoft.com/en-us/sysinternals/bb896651
usage: du [-c] [-l <levels> | -n | -v] [-u] [-q] <directory>
-c Print output as CSV.
-l Specify subdirectory depth of information (default is all levels).
-n Do not recurse.
-q Quiet (no banner).
-u Count each instance of a hardlinked file.
-v Show size (in KB) of intermediate directories.
C:\SysInternals>du -n d:\temp
Du v1.4 - report directory disk usage
Copyright (C) 2005-2011 Mark Russinovich
Sysinternals - www.sysinternals.com
Files: 26
Directories: 14
Size: 28.873.005 bytes
Size on disk: 29.024.256 bytes
Kiedy już to zrobisz, spójrz na inne narzędzia. Są ratunkiem dla każdego systemu Windows Professional
\\live.sysinternals.com
jeśli nadal istnieje). Całkowicie zgadzam się jednak, że wszystkie narzędzia systemowe powinny być domyślnie włączone. Chociaż dla wielu zastosowań PowerShell jest całkiem godnym zamiennikiem.
Oneliner:
powershell -command "$fso = new-object -com Scripting.FileSystemObject; gci -Directory | select @{l='Size'; e={$fso.GetFolder($_.FullName).Size}},FullName | sort Size -Descending | ft @{l='Size [MB]'; e={'{0:N2} ' -f ($_.Size / 1MB)}},FullName"
To samo, ale tylko Powershell:
$fso = new-object -com Scripting.FileSystemObject
gci -Directory `
| select @{l='Size'; e={$fso.GetFolder($_.FullName).Size}},FullName `
| sort Size -Descending `
| ft @{l='Size [MB]'; e={'{0:N2} ' -f ($_.Size / 1MB)}},FullName
Powinno to dać następujący wynik:
Size [MB] FullName
--------- --------
580,08 C:\my\Tools\mongo
434,65 C:\my\Tools\Cmder
421,64 C:\my\Tools\mingw64
247,10 C:\my\Tools\dotnet-rc4
218,12 C:\my\Tools\ResharperCLT
200,44 C:\my\Tools\git
156,07 C:\my\Tools\dotnet
140,67 C:\my\Tools\vscode
97,33 C:\my\Tools\apache-jmeter-3.1
54,39 C:\my\Tools\mongoadmin
47,89 C:\my\Tools\Python27
35,22 C:\my\Tools\robomongo
0.00 C:\Windows
czy mogę to zoptymalizować dla wszystkich folderów, próbowałem już uruchomić jako admin
ft
( Format-Table
). Możesz spróbować fl
zamiast tego ( Format-List
)
Jeśli masz zainstalowanego git na swoim komputerze (staje się coraz bardziej powszechny), po prostu otwórz MINGW32 i wpisz: du folder
du -h -d 1 folder | sort -h
jeśli chcesz mieć rozmiar czytelny dla człowieka, tylko jeden poziom podkatalogów i sortować według rozmiaru.
Polecam skorzystać z https://github.com/aleksaan/diskusage narzędzia . Bardzo proste i pomocne. I bardzo szybko.
Po prostu wpisz powłokę poleceń
diskusage.exe -path 'd:/go; d:/Books'
i uzyskaj listę folderów uporządkowanych według rozmiaru
1. | DIR: d: / go | ROZMIAR: 325,72 Mb | GŁĘBOKOŚĆ: 1 2. | DIR: d: / Książki | ROZMIAR: 14.01 Mb | GŁĘBOKOŚĆ: 1
Ten przykład został wykonany przy 272 ms na dysku twardym.
Możesz zwiększyć głębokość podfolderów do analizy, na przykład:
diskusage.exe -path 'd:/go; d:/Books' -depth 2
i uzyskaj rozmiary nie tylko dla wybranych folderów, ale także dla ich podfolderów
1. | DIR: d: / go | ROZMIAR: 325,72 Mb | GŁĘBOKOŚĆ: 1 2. | DIR: d: / go / pkg | ROZMIAR: 212,88 Mb | GŁĘBOKOŚĆ: 2 3. | DIR: d: / go / src | ROZMIAR: 62,57 Mb | GŁĘBOKOŚĆ: 2 4. | DIR: d: / go / bin | ROZMIAR: 30,44 Mb | GŁĘBOKOŚĆ: 2 5. | DIR: d: / Książki / Szachy | ROZMIAR: 14.01 Mb | GŁĘBOKOŚĆ: 2 6. | DIR: d: / Książki | ROZMIAR: 14.01 Mb | GŁĘBOKOŚĆ: 1 7. | DIR: d: / go / api | ROZMIAR: 6,41 Mb | GŁĘBOKOŚĆ: 2 8. | DIR: d: / go / test | ROZMIAR: 5,11 Mb | GŁĘBOKOŚĆ: 2 9. | DIR: d: / go / doc | ROZMIAR: 4,00 Mb | GŁĘBOKOŚĆ: 2 10. | DIR: d: / go / misc | ROZMIAR: 3,82 Mb | GŁĘBOKOŚĆ: 2 11. | DIR: d: / go / lib | ROZMIAR: 358,25 Kb | GŁĘBOKOŚĆ: 2
* 3,5 TB na serwerze zostało przeskanowane pod kątem 3m12s
Oto kod PowerShell, który piszę, aby wyświetlić rozmiar listy i liczbę plików dla wszystkich folderów w bieżącym katalogu. Zapraszam do ponownego wykorzystania lub modyfikacji zgodnie z potrzebami.
$FolderList = Get-ChildItem -Directory
foreach ($folder in $FolderList)
{
set-location $folder.FullName
$size = Get-ChildItem -Recurse | Measure-Object -Sum Length
$info = $folder.FullName + " FileCount: " + $size.Count.ToString() + " Size: " + [math]::Round(($size.Sum / 1GB),4).ToString() + " GB"
write-host $info
}
$FolderList = Get-ChildItem -Directory -Force; $data = foreach ($folder in $FolderList) { set-location $folder.FullName; $size = Get-ChildItem -Recurse -Force | Measure-Object -Sum Length; $size | select @{n="Path"; e={$folder.Fullname}}, @{n="FileCount"; e={$_.count}}, @{n="Size"; e={$_.Sum}} }
to zapewni obiekty (więcej Powershell-ish), „FileCount” i „Size” to liczby całkowite (więc w razie potrzeby można je później przetworzyć), a „Size” jest w bajtach, ale można je łatwo przekonwertować na GB (lub żądana jednostka) z $Data.Size / 1GB
.
$Data = dir -Directory -Force | %{ $CurrentPath = $_.FullName; Get-ChildItem $CurrentPath -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Sum Length | select @{n="Path"; e={$CurrentPath}}, @{n="FileCount"; e={$_.count}}, @{n="Size"; e={$_.Sum}} }
Ten kod jest testowany. Możesz to sprawdzić ponownie.
@ECHO OFF
CLS
SETLOCAL
::Get a number of lines contain "File(s)" to a mytmp file in TEMP location.
DIR /S /-C | FIND "bytes" | FIND /V "free" | FIND /C "File(s)" >%TEMP%\mytmp
SET /P nline=<%TEMP%\mytmp
SET nline=[%nline%]
::-------------------------------------
DIR /S /-C | FIND "bytes" | FIND /V "free" | FIND /N "File(s)" | FIND "%nline%" >%TEMP%\mytmp1
SET /P mainline=<%TEMP%\mytmp1
CALL SET size=%mainline:~29,15%
ECHO %size%
ENDLOCAL
PAUSE
Wydaje mi się, że zadziałałoby to tylko wtedy, gdy katalog jest dość statyczny, a jego zawartość nie zmienia się między wykonaniem dwóch poleceń dir. Może sposób na połączenie tego w jedno polecenie, aby tego uniknąć, ale to zadziałało w moim celu (nie chciałem pełnej listy; tylko podsumowanie).
Skrypt GetDirSummary.bat:
@echo off
rem get total number of lines from dir output
FOR /F "delims=" %%i IN ('dir /S %1 ^| find "asdfasdfasdf" /C /V') DO set lineCount=%%i
rem dir summary is always last 3 lines; calculate starting line of summary info
set /a summaryStart="lineCount-3"
rem now output just the last 3 lines
dir /S %1 | more +%summaryStart%
Stosowanie:
GetDirSummary.bat c: \ temp
Wynik:
Total Files Listed:
22 File(s) 63,600 bytes
8 Dir(s) 104,350,330,880 bytes free
Dostałem du.exe
z moją dystrybucją git. Innym miejscem może być wspomniany wcześniej Microsoft lub Unxutils .
Gdy już masz du.exe na swojej ścieżce. Oto twój fileSizes.bat
:-)
@echo ___________
@echo DIRECTORIES
@for /D %%i in (*) do @CALL du.exe -hs "%%i"
@echo _____
@echo FILES
@for %%i in (*) do @CALL du.exe -hs "%%i"
@echo _____
@echo TOTAL
@du.exe -sh "%CD%"
➪
___________
DIRECTORIES
37M Alps-images
12M testfolder
_____
FILES
765K Dobbiaco.jpg
1.0K testfile.txt
_____
TOTAL
58M D:\pictures\sample
Myślę, że jedyną opcją będzie diruse (wysoce obsługiwane rozwiązanie innej firmy):
Uzyskaj rozmiar pliku / katalogu z wiersza poleceń
Windows CLI jest niestety dość restrykcyjny, możesz alternatywnie zainstalować Cygwin, który jest marzeniem w porównaniu do cmd. To dałoby dostęp do przeniesionego narzędzia Unix du, które jest podstawą dirusów w systemie Windows.
Przepraszam, że nie mogłem odpowiedzieć na twoje pytania bezpośrednio poleceniem, które możesz uruchomić na natywnej klinie.
:: Pobierz liczbę wierszy zwracanych przez polecenia Dir (/ -c, aby wyeliminować separatory liczb:.,) ["Tokens = 3", aby spojrzeć tylko na trzecią kolumnę każdego wiersza w Dir]
FOR /F "tokens=3" %%a IN ('dir /-c "%folderpath%"') DO set /a i=!i!+1
Numer przedostatniej linii, gdzie jest liczbą bajtów sumy plików:
set /a line=%i%-1
Na koniec uzyskaj liczbę bajtów w przedostatnim wierszu - 3 kolumnie:
set i=0
FOR /F "tokens=3" %%a IN ('dir /-c "%folderpath%"') DO (
set /a i=!i!+1
set bytes=%%a
If !i!==%line% goto :size
)
:size
echo %bytes%
Ponieważ nie wykorzystuje wyszukiwania słów, nie miałby problemów językowych.
Ograniczenia:
Próbować:
SET FOLDERSIZE=0
FOR /F "tokens=3" %A IN ('DIR "C:\Program Files" /a /-c /s ^| FINDSTR /C:" bytes" ^| FINDSTR /V /C:" bytes free"') DO SET FOLDERSIZE=%A
Zmień C: \ Program Files na dowolny folder i zmień% A na %% A, jeśli używasz w pliku wsadowym
Zwraca rozmiar całego folderu, w tym podfolderów oraz plików ukrytych i systemowych, i współpracuje z folderami powyżej 2 GB
Zapisuje na ekranie, więc jeśli nie chcesz, będziesz musiał użyć pliku tymczasowego.
Poniższego skryptu można użyć do pobrania i zgromadzenia rozmiaru każdego pliku w danym folderze.
Ścieżkę do folderu %folder%
można podać jako argument dla tego skryptu ( %1
).
Ostatecznie wyniki są przechowywane w parametrze%filesize%
@echo off
SET count=1
SET foldersize=0
FOR /f "tokens=*" %%F IN ('dir /s/b %folder%') DO (call :calcAccSize "%%F")
echo %filesize%
GOTO :eof
:calcAccSize
REM echo %count%:%1
REM set /a count+=1
set /a foldersize+=%~z1
GOTO :eof
Uwaga: metoda calcAccSize
może również wydrukować zawartość folderu (skomentowaną w powyższym przykładzie)
Oto rozwiązanie dla obu twoich żądań w sposób, o który prosiłeś. Zapewni to rozmiar pliku czytelny dla człowieka bez ograniczeń rozmiaru pliku, z którymi wszyscy się spotykają. Kompatybilny z Win Vista lub nowszym. XP jest dostępny tylko wtedy, gdy zainstalowany jest Robocopy. Po prostu upuść folder na ten plik wsadowy lub użyj lepszej metody wymienionej poniżej.
@echo off
setlocal enabledelayedexpansion
set "vSearch=Files :"
For %%i in (%*) do (
set "vSearch=Files :"
For /l %%M in (1,1,2) do (
for /f "usebackq tokens=3,4 delims= " %%A in (`Robocopy "%%i" "%%i" /E /L /NP /NDL /NFL ^| find "!vSearch!"`) do (
if /i "%%M"=="1" (
set "filecount=%%A"
set "vSearch=Bytes :"
) else (
set "foldersize=%%A%%B"
)
)
)
echo Folder: %%~nxi FileCount: !filecount! Foldersize: !foldersize!
REM remove the word "REM" from line below to output to txt file
REM echo Folder: %%~nxi FileCount: !filecount! Foldersize: !foldersize!>>Folder_FileCountandSize.txt
)
pause
Aby móc wygodnie korzystać z tego pliku wsadowego, umieść go w folderze SendTo. Umożliwi to kliknięcie folderu lub wybór folderów prawym przyciskiem myszy, kliknięcie opcji Wyślij do, a następnie wybranie tego pliku wsadowego.
Aby znaleźć folder SendTo na komputerze, najprostszym sposobem jest otwarcie polecenia cmd, a następnie skopiowanie w tym wierszu bez zmian.
explorer C:\Users\%username%\AppData\Roaming\Microsoft\Windows\SendTo
Rozwiązałem podobny problem. Niektóre metody na tej stronie są powolne, a niektóre są problematyczne w środowisku wielojęzycznym (wszystkie zakładają angielski). Znalazłem proste obejście za pomocą vbscript w cmd. Jest testowany w W2012R2 i W7.
>%TEMP%\_SFSTMP$.VBS ECHO/Set objFSO = CreateObject("Scripting.FileSystemObject"):Set objFolder = objFSO.GetFolder(%1):WScript.Echo objFolder.Size
FOR /F %%? IN ('CSCRIPT //NOLOGO %TEMP%\_SFSTMP$.VBS') DO (SET "S_=%%?"&&(DEL %TEMP%\_SFSTMP$.VBS))
Ustawia zmienną środowiskową S_. Możesz oczywiście zmienić ostatnią linię, aby bezpośrednio wyświetlać wynik np
FOR /F %%? IN ('CSCRIPT //NOLOGO %TEMP%\_SFSTMP$.VBS') DO (ECHO "Size of %1 is %%?"&&(DEL %TEMP%\_SFSTMP$.VBS))
Możesz go używać jako podprogramu lub jako samodzielny cmd. Parametr to nazwa testowanego folderu zamknięta w cudzysłowie.