【发布时间】:2017-12-18 18:53:56
【问题描述】:
我想获取特定路径中每个文件/文件夹的大小并将其输出到文件中。
我在 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
【问题讨论】:
-
DirectoryName和Folder1并不能真正区分。你仍然会得到旁边的尺寸。很难让它既递归又像你正在做的自动缩进 -
缩进并不是我真正关注的重点,它更多的是关于我在顶部获得
DirectoryName的格式,然后是这个特定目录中的所有文件,等等。只要它遵循格式,它就可以完全没有缩进 -
我过去做过这个。我没有时间写出答案,但我会告诉你我使用了递归并将缩进级别传递给递归函数,然后该函数在调用自身之前递增缩进。
-
哦,为了确保在列出新文件之前先获取目录,然后是该目录中的文件列表,请始终只为文件执行 Get-ChildItem,然后再为进一步递归执行另一个。
-
这些都是很好的起点,我会这样看!谢谢@EBGreen
标签: powershell recursion file-io