简体   繁体   English

如何递归获取PowerShell、自定义output中所有文件和文件夹的大小

[英]How to recursively get the size of all files and folders in PowerShell, custom output

I want to get the size of each files/folders in a specific path and output it in a file.我想在特定路径中获取每个文件/文件夹的大小,并将 output 它放在一个文件中。

I played with PowerShell as far as I could with my very limited PowerShell knowledge and look through many posts yet I can't seem to find a way to output it as I need it.我用我非常有限的 PowerShell 知识尽我所能玩 PowerShell 并浏览了很多帖子,但我似乎找不到 output 的方法,因为我需要它。

Currently, I have the below script, thanks to this post .目前,我有以下脚本,感谢这篇文章

$folderToBeListed = "PATH";
$folder = (Get-ChildItem $folderToBeListed -recurse | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object)

foreach ($i in $folder)
{
    $i.DirectoryName
    $subFolderItems = (Get-ChildItem $i.FullName | Measure-Object -property Length -sum | Select-Object Sum)
    $i.Name + " -- " + "{0:N2}" -f ($subFolderItems.sum /1MB) + " MB"

}

<#
$date = "$(Get-Date -f yyyy-MM-dd@HH)h$(Get-Date -f mm)m$(Get-Date -f ss)s"
Out-File PATH\filesSizes_$date.txt
#>

This outputs the below format:这将输出以下格式:

DirectoryName -- size MB
FileName -- size MB
DirectoryName
FileName -- size MB

I would like the output to be like this:我希望 output 是这样的:

DirectoryName -- size MB
    FileName1 -- size MB
    FileName2 -- size MB
    Folder1 -- size MB
        FileName3 -- size MB
        FileName4 -- size MB
    Folder2 -- size MB
        FileName5 -- size MB
DirectoryName2 -- size MB
...

Is there a way to go through all the files and folders recursively to format them in such a way or do I have to keep formatting the output with the DirectoryName over the file and then filter them by directory name?有没有办法通过所有文件和文件夹递归地 go 以这种方式格式化它们,还是我必须继续用文件上的DirectoryName格式化 output 然后按目录名称过滤它们?

Then I would like to output the result in a file (the commented part is my starting point yet I don't know what to feed the Out-File.然后我想 output 将结果保存在一个文件中(注释部分是我的起点,但我不知道该提供什么输出文件。

Update更新

The indentation is optional.缩进是可选的。 I put it so it shows more visually what I intend to get as the output but really, the below output would be fine.我这样说是为了更直观地显示我想要得到的 output 但实际上,下面的 output 会很好。

DirectoryName -- size MB
FileName1 -- size MB
FileName2 -- size MB
Folder1 -- size MB
FileName3 -- size MB
FileName4 -- size MB
Folder2 -- size MB
FileName5 -- size MB
DirectoryName2 -- size MB
...

Update 2更新 2

This is an update of what I currently have.这是我目前拥有的更新。 It still has flaws and is not right yet.它仍然有缺陷,而且还不正确。 I will describe the problems with this below the code.我将在代码下面描述这个问题。

$folderToBeListed = "PATH";
$elements = Get-ChildItem $folderToBeListed -recurse
$originSize = getSizeFolder -path $folderToBeListed
"Listed folder : " + $folderToBeListed + " -- Size : " + $originSize + " MB"| Out-String

foreach ($i in $elements)
{
    if($i.PSIsContainer -eq $True)
    {
        try
        {
            $folderSize = getSizeFolder -path $i.FullName

            "`n`nFolder -- " + $i.Name + " -- Size : " + $folderSize + " MB" | Out-String 

            foreach ($it in (Get-ChildItem $i.FullName -recurse))
            {
                $fileSize = getSizeFile -path $it.FullName
                $it.Name + " -- " + $fileSize + " KB"
            }

        }
        catch
        {
            "NOOO (It's a catch, line ~28)" | Out-String
        }
    }
    else
    {
        $i.Name + " -- " + $fileSize + " KB"
    }    
}

function getSizeFolder($path)
{
   $sizeFolder = (Get-Item $path).GetFiles() | Measure-Object -Sum Length
   return $sizeFolder.Sum / 1000000 <#Supposed MB#>
}

function getSizeFile($path)
{
    $sizeFile = (Get-Item $path).Length
    return $sizeFile / 1000 <#Supposed KB#>
}

Alright so the situations I have encounter yet are the following:好的,所以我遇到的情况如下:

1- If there is a folder containing other folder, it does list every folder and files inside only. 1-如果有一个文件夹包含其他文件夹,它只列出每个文件夹和里面的文件。

Folder -- DirectoryName -- Size XX MB
Folder1 -- Size XX KB
Folder2 -- Size XX KB
FileInFolder1 -- Size XX KB
...

2- If there is only folders containing files, it shows it fine. 2-如果只有文件夹包含文件,它显示它很好。

Folder -- DirectoryName -- Size XX MB
File1 -- Size XX KB
File2 -- Size XX KB
Folder2 -- DirectoryName -- Size XX MB
File3 -- Size XX KB
File4 -- Size XX KB
...

That being said, I still have all the files listed in the end because of the else clause...话虽如此,由于 else 子句,我仍然拥有最后列出的所有文件......

Update 3更新 3

Took a bit of different approach.采取了一些不同的方法。 This does list all the folders and the files in the chosen folder yet I have no implemented the "recursiveness" yet.这确实列出了所选文件夹中的所有文件夹和文件,但我还没有实现“递归”。 Still trying to figure out the algorithm I'll use for it to work.仍在试图找出我将使用它来工作的算法。 I have also not already started the write operation in a txt file.我还没有在 txt 文件中开始写操作。 All the help is appreciated !感谢所有帮助!

function getFoldersInFolder($path)
{
    [array]$elements = Get-ChildItem $path | Where-Object {$_.PSIsContainer}
    return $elements
}

function getFilesInFolder($path)
{
    [array]$elements = Get-ChildItem $path | Where-Object {!$_.PSIsContainer}
    return $elements
}

function getSizeFolder($path)
{
   $sizeFolder = (Get-Item $path).GetFiles() | Measure-Object -Sum Length

   if($sizeFolder.Sum -lt 1000)<#Octets#>
   {
        if($sizeFolder.Sum -eq $Null)<#The folder contains only folders#>
        {
            return "`n`nThe size is null (th efolder only contains folders.)`nThe sizes of each folder will be displayed below."
        }
        else
        {
            return "{0:N2}" -f $sizeFolder.Sum + " octets"
        }
   }
   elseif($sizeFolder.Sum -gt 1000 -and $sizeFolder.Sum -lt 999999)<#Ko#>
   {
       return "{0:N2}" -f ($sizeFolder.Sum / 1000) + " Ko"
   }
   elseif($sizeFolder.Sum -gt 1000000 -and $sizeFolder.Sum -lt 999999999)<#Mo#>
   {
       return "{0:N2}" -f ($sizeFolder.Sum / 1000000) + " Mo"
   }
   elseif($sizeFolder.Sum -gt 1000000000 -and $sizeFolder.Sum -lt 999999999999)<#Go#>
   {
       return "{0:N2}" -f ($sizeFolder.Sum / 1000000000) + " Go"     
   }

}

function getSizeFile($path)
{
   $sizeFile = (Get-Item $path).Length

   if($sizeFile -lt 1000)<#Octets#>
   {
        return "{0:N2}" -f $sizeFile + " octets"
   }
   elseif($sizeFile -gt 1000 -and $sizeFile -lt 999999)<#Ko#>
   {
       return "{0:N2}" -f ($sizeFile / 1000) + " Ko"
   }
   elseif($sizeFile -gt 1000000 -and $sizeFile -lt 999999999)<#Mo#>
   {
       return "{0:N2}" -f ($sizeFile / 1000000) + " Mo"
   }
   elseif($sizeFile -gt 1000000000 -and $sizeFile -lt 999999999999)<#Go#>
   {
       return "{0:N2}" -f ($sizeFile / 1000000000) + " Go"     
   }
}

function main()
{
    $folder = "{INPUT PATH HERE}"

    $originFolderSize = getSizeFolder -path $folder

    Write-Host "`nBelow are the files/folders from : $folder => Size : $originFolderSize `n"    

    <#List all folders#>

    [array]$foldersInFolder = getFoldersInFolder -path $folder

    for($i = 0; $i -lt $foldersInFolder.Count; $i++)
    {
        ##$foldersInFolder[$i] | Out-String

        $tempPath = $folder + "\" + $foldersInFolder[$i]

        $tempFolderSize = getSizeFolder -path $tempPath

        Write-Host FOLDER => $foldersInFolder[$i] => Size : $tempFolderSize`n        
    }

    <#List all files#>
    [array]$filesInFolder = getFilesInFolder -path $folder

    for($i = 0; $i -lt $filesInFolder.Count; $i++)
    {
        ##$filesInFolder[$i] | Out-String

        $tempPath = $folder + "\" + $filesInFolder[$i]

        $tempFileSize = getSizeFile -path $tempPath

        Write-Host FILE => $filesInFolder[$i] => Size : $tempFileSize`n
    }

}

main

This does outputs like this:这会像这样输出:

Below are the files/folders from : PATH => Size : XX,XX Mo
FOLDER1 => Folder1Name => Size : XX,XX Mo
FOLDER2 => Folder2Name => Size : XX,XX Ko
FILE1 => File1Name => Size : XX,XX Mo
FILE2 => File2Name => Size : XX,XX Go
FILE3 => File3Name => Size : XX,XX Ko

I was looking for the same but for directories only in a delimited deep level.我一直在寻找相同的目录,但仅在分隔的深层目录中。 Also, i need eficience not recalculing subdirectories size yet calculated in a previous recursive iteration.此外,我需要效率而不是重新计算在先前的递归迭代中计算的子目录大小。 Using many examples finaly i wrote my own solution:最后使用了许多示例,我编写了自己的解决方案:

powershell -command ".\scriptMida.ps1 -Directory c:\hp -level 2 -HiddeErrors"

Temps#nivell#DirectoryPath#FileSize#FileSize(MB)#FileSize(GB)
2022/07/16 01:21#2#C:\hp\BIN#347095#0.33#0
2022/07/16 01:21#2#C:\hp\bridge#2460#0#0
2022/07/16 01:21#3#C:\hp\HPQWare\bridge#2460#0#0
2022/07/16 01:21#3#C:\hp\HPQWare\browser#78553#0.07#0
2022/07/16 01:21#3#C:\hp\HPQWare\BTBHost#715797#0.68#0
2022/07/16 01:21#3#C:\hp\HPQWare\Favs#6098#0.01#0
2022/07/16 01:21#3#C:\hp\HPQWare\Netflix#76#0#0
2022/07/16 01:21#3#C:\hp\HPQWare\Simplesolitaire#6#0#0
2022/07/16 01:21#2#C:\hp\HPQWare#803076#0.77#0.00
2022/07/16 01:21#2#C:\hp\McAfeeRules#8014#0.01#0
2022/07/16 01:21#3#C:\hp\support\flexroot#152866#0.15#0
2022/07/16 01:21#2#C:\hp\support#320415#0.31#0.00

The code is in github https://github.com/elmeuavi/RecursiveDirSize with examples and with also another "human" presentation and with a secondary script to compare 2 executions of same directories.该代码位于 github https://github.com/elmeuavi/RecursiveDirSize中,带有示例和另一个“人类”演示文稿,以及用于比较相同目录的 2 次执行的辅助脚本。

It can be easy to you to modify it adding at the output the files of each directory you enter in the recursive function and changing output presentation if you desire.您可以轻松地对其进行修改,在 output 中添加您在递归 function 中输入的每个目录的文件,并根据需要更改 output 演示文稿。

Look up the these two commands, they might be of use: 查找以下两个命令,它们可能有用:

df

dh

Here is an example of getting sizes of things with a max depth of two directories and in human format (not 512 byte blocks) 这是获取具有两个目录的最大深度且采用人类格式(不是512字节块)的事物的大小的示例

> du -h --max-depth=2
 1.0K    ./.docker
 1.0K    ./.eclipse/org.eclipse.epp.logging.aeri
 2.0K    ./.eclipse/org.eclipse.oomph.jreinfo
 2.6M    ./.eclipse/org.eclipse.oomph.p2
 578K    ./.eclipse/org.eclipse.oomph.setup
 1.0K    ./.eclipse/org.eclipse.oomph.setup.installer
 3.2M    ./.eclipse
 209M    ./.m2/repository
 209M    ./.m2
 0       ./.matplotlib
 0       ./.nbi/downloads
 5.0M    ./.nbi/log
 364K    ./.nbi/product-cache
 317K    ./.nbi/tmp
 0       ./.nbi/wd
 5.8M    ./.nbi
 109K    ./.p2/org.eclipse.equinox.p2.core
 467K    ./.p2/org.eclipse.equinox.p2.engine
 2.5M    ./.p2/org.eclipse.equinox.p2.repository
 203M    ./.p2/pool
 206M    ./.p2
 6.0K    ./.ssh
 68K     ./.tooling/gradle
 68K     ./.tooling

This worked on my Win10 PowerShell. 这适用于我的Win10 PowerShell。 Your success may vary. 您的成功可能会有所不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何递归删除 PowerShell 中的所有空文件夹? - How to recursively remove all empty folders in PowerShell? PowerShell:递归获取所有子项-没有bin / obj文件夹 - PowerShell: get all child items recursively - without bin/obj folders Powershell:如何在文件夹中递归创建文本文件? - Powershell: How can I create text files within folders recursively? 如何以递归方式查找PowerShell中包含.hg文件夹的所有文件夹 - How to recursively find all folders containing a .hg folder in PowerShell 如何在powershell中递归获取所有子项 - How to get all child recursively in powershell 如何使用Powershell获取文件夹中所有文件夹名称而不是子文件夹中文件/子文件夹的.txt文件? - How to get a .txt file of all folders names inside a folder but not the files/subfolders inside the child folders using powershell? PowerShell 获取视频时长并递归列出所有文件,导出到 csv - PowerShell Get video duration and list all files recursively, export to csv 递归获取 PowerShell 中大小的文件 - Get recursively files with sizes in PowerShell Map 递归应用到目录中的所有文件夹/文件 - Map an app to all folders/files in a directory recursively 如何使用 Powershell 递归重命名文件夹? - How do I recursively rename folders with Powershell?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM