这个powershell程序中最大的文件



我需要两件简单的事情,我的程序要求用户输入一个目录,我需要一种方法,如果没有输入任何内容,则使用默认目录。

其次,从给定的目录中找到最大的文件。

我被告知要使用:

Get-ChildItem c:temp | Sort Length -desc | Select-Object -First 1

但对我来说,这可能是中国式的。我只懂Java。我得到了它应该做的事情,但它在我的代码中什么都没做:

$a = Read-Host “Enter directory”
function Get-Size {
  param ($Path)
  $Size = 0
  foreach ($Folder in (Get-ChildItem $Path)) {
      if ($Folder.PSIsContainer) {
        Get-Size $Folder.FullName
      } else {
        $Size += $Folder.Length
      }
  }
  New-Object PSObject -Property @{'Size in KB'=$Size/100; 'Folder'=$Path}
}
Write-Host "Disk space use (in KB) for each subdirectory:"
Get-Size $a

好吧,您的代码有一些问题,但首先我将回答您提出的问题。

1.向用户询问目录,如果未输入任何内容,则使用默认目录

要让函数为任何参数使用默认值,只需在参数声明的末尾添加= defaultvalue即可。在这种情况下,

param (
  $Path = 'C:MyDefaultDirectory'
)

如果你不希望函数使用默认目录,但希望脚本在提示用户时分配默认目录,你可以这样做:

if (! ($a = Read-Host 'Enter directory')) {
  $a = 'C:MyDefaultDirectory'
}

if条件执行$a = Read-Host 'Enter directory',并在用户未输入任何内容的情况下执行为$a分配默认值的块(赋值语句的计算结果为分配给变量的值,空字符串为假值,因此如果用户在未提供值的情况下点击enter,则(! ($a = Read-Host 'Enter directory'))为真)。

2.在目录中查找最大值

给你的命令有效:

 Get-ChildItem c:temp | Sort Length -desc | Select-Object -First 1

你说它在你的代码中什么都不做,但我甚至没有在你的码中看到它。如果你展示你在哪里/如何添加它,我就能告诉你为什么它看起来毫无作用。这可能与你如何使用结果有关。现在我可以解释它是如何工作的。

  • Get-ChildItem C:Temp |当然列出C:\Temp的内容,并将结果(表示目录中每个项的FileInfo对象)发送到管道
  • Sort Length -desc |按降序对结果进行排序,并将排序后的结果发送到管道中排序排序对象的缩写,长度为包含以字节为单位的文件大小的FileInfo对象的属性,而-desc则是-Descending缩写
  • Select-Object -First 1从结果中选择第一项。由于它们是按文件大小降序排列的,所以第一项是表示最大文件的FileInfo对象

您的代码中的一些其他问题与问题没有直接关系

  • PowerShell是为使用管道而设计的。代替

    foreach ($Folder in (Get-ChildItem $Path)) {
    

    使用

    Get-ChildItem $Path | %{
    

    它在打字和处理方面都更高效%{}ForEach对象的缩写(ForEach循环不同;它是一个用于管道的过滤器,通常运行效率更高)。

  • $Size/100不会给出以KB为单位的大小,因为1 KB是1024字节,但有一个内置的缩写:

    $Size / 1KB. 
    

    你也可以使用1MB1GB1TB1PB(对不起,现在还没有1EB,但我相信5-10年后不仅会有,它可能会非常频繁地使用)。请注意,可以更改系数,但不能忽略它(/ 2GB除以2GB,但没有1/ GB是语法错误)

  • 不需要使用递归函数来完成此操作。PowerShell内置了递归遍历目录树和求和结果的功能。下面是一个展示如何做到这一点的版本,结合上面的建议:

    function Get-Size {
      param (
        $Path  = 'C:MyDefaultDirectory'
      )
      Get-ChildItem $Path -Recurse | ?{$_.PSIsContainer} | %{
        $Size = (Get-ChildItem $_.FullName | Measure-Object Length -Sum -ea SilentlyContinue).Sum
        New-Object PSObject -Property @{'Size in KB' = ($Size / 1KB); 'Folder' = $_.FullName}
      }
    }
    
  • 输出将相当混乱,因此您可能希望通过管道将结果传送到格式化表。我认为最好在调用函数时进行格式化,而不是将其包含在函数定义本身中。这将按照您可能想要的顺序为您提供属性,大小正确对齐并固定在小数点后两位的精度:

    Get-Size $a | Format-Table @{Name = 'Size in KB'; Expression = {"{0:N2}" -f $_.'Size in KB'}; Align = 'right'}, ' ', Folder -AutoSize
    

首先,Frode F.说的是对的。如果您需要使用PowerShell,请学习PowerShell。来到这里,陈述你所做的事情会让人觉得"我是一个java人,我不懂PowerShell,帮我解决它,因为我要么太忙了,搞不清楚,要么就在我下面"。要求我们纠正你似乎没有花时间尝试和理解的事情,是在滥用我们免费提供的服务。我现在就下车帮你。

您的请求和代码说明了两件截然不同的事情。您的脚本获取文件夹中所有内容的总大小,并递归地获取所有子文件夹的总大小。您的请求是只查找该文件夹中最大的文件。

实际上,您有两个请求。用于默认文件夹的文件夹很简单。如果没有给定路径,则设置默认值只需正确设置参数即可。如果在"参数"部分中为参数设置了值,则如果未输入值,则该值将被视为默认值。这样做将为您解决问题:

Function Get-Size{
Param ($Path="$env:USERPROFILEDesktop")
<code goes here>
}

将默认设置为当前用户的Desktop文件夹。

至于获得最大的文件,给你的代码会做到这一点。让我解释一下。

CCD_ 16为CCD_。管道(|)将该信息发送到下一个命令,即Sort

Sort Length -desc按长度(实际上是文件大小)按降序对第一个命令的结果进行排序。它通过管道传输到Select

Select-Object -first 1选择前1个结果(您可以使用-first 3选择前3个结果,也可以不使用)。由于它们已经按降序排列,因此它会选择指定路径中最大的文件。

请注意,这不是递归运行的。要使其搜索所有文件夹并返回最大的文件,请在Get-ChildItem命令中添加-recurse开关。

至于你的脚本,好吧,它完成了它想要做的事情。它得到了每个文件夹和子文件夹的完整大小并报告回来。它的操作方式有点笨拙,但它是功能性的。至于我,我想我会做一些更像这样的事情:

Function Get-Size{
Param ([Parameter(ValueFromPipeline=$True)]
    $Path="$env:USERPROFILEDesktop")
    ForEach ($Folder in (Get-ChildItem $Path -recurse|?{$_.PSIsContainer})) {
        $Size = (Get-ChildItem $Folder.FullName | Measure-Object -property length -sum -ea SilentlyContinue)
        New-Object PSObject -Property @{'Size in KB'="{0:N2}" -f ($Size.sum/1KB) +" KB"; 'Folder'=$Folder.FullName}
    }
}
Read-Host "Enter a path" | Get-Size

最新更新