powershell - 如何递归获取PowerShell中自定义输出中所有文件和文件夹的大小

标签 powershell recursion file-io

我想获取特定路径中每个文件/文件夹的大小,并将其输出到文件中。

我以非常有限的PowerShell知识来尽可能地使用PowerShell,并浏览了许多文章,但似乎找不到找到所需的输出方法。

当前,由于有了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
#>

输出以下格式:
DirectoryName -- size MB
FileName -- size MB
DirectoryName
FileName -- size MB

我希望输出是这样的:
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
...

有没有一种方法可以递归地浏览所有文件和文件夹,以这种方式对其进行格式化,还是我必须继续在文件上使用DirectoryName格式化输出,然后按目录名称对其进行过滤?

然后,我想将结果输出到文件中(带注释的部分是我的出发点,但我不知道该如何提供输出文件。

更新

缩进是可选的。我放了它,这样可以更直观地显示我打算作为输出获得什么,但实际上,下面的输出会很好。
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
...

更新2

这是我目前所拥有的更新。它仍然存在缺陷,并且还不正确。我将在代码下面描述与此有关的问题。
$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#>
}

好的,所以我遇到的情况如下:

1-如果存在包含其他文件夹的文件夹,则仅列出其中的每个文件夹和文件。
Folder -- DirectoryName -- Size XX MB
Folder1 -- Size XX KB
Folder2 -- Size XX KB
FileInFolder1 -- Size XX KB
...

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

话虽如此,由于else子句,我仍然在最后列出所有文件...

更新3

采取了一些不同的方法。这确实列出了所有文件夹和所选文件夹中的文件,但是我还没有实现“递归”。仍在尝试弄清楚我将使用的算法。我还没有开始在txt文件中进行写操作。感谢所有的帮助!
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

这样的输出如下:
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

最佳答案

查找以下两个命令,它们可能有用:

df

dh

这是获取具有两个目录的最大深度且采用人类格式(不是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

这适用于我的Win10 PowerShell。您的成功可能会有所不同。

关于powershell - 如何递归获取PowerShell中自定义输出中所有文件和文件夹的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47874711/

相关文章:

android - 如何在 Android 应用程序中将文本字段(用户输入)数据保存在文本文件中

windows - 将 PowerShell 转换为 Bash

powershell - 如何一次将一个字符发送到 powershell 中的函数?

c - 如何递归遍历哈夫曼树以搜索特定元素? - C

r - 列出 k 个数字的所有排列,取自 0 :k,,总和为 k

php - 打开文件夹而没有PHP警告

c++ - 是否有等价物可以在不同平台上传播?

.net - 作为服务运行时找不到 PowerShell 模块

windows - 在 Powershell 中为另一本地用户登录时触发的一次性计划任务

bash - 递归搜索文件