【问题标题】:How do I filter directories with powershell on the amount of files contained如何使用 powershell 根据包含的文件数量过滤目录
【发布时间】:2015-06-13 14:08:24
【问题描述】:

我在寻找正确的语法时遇到问题,我需要过滤我的结果,仅列出文件数超过指定数量(在我的情况下为 600)的目录。

这是我目前的代码;

$server_dir= "D:\backup"
$export_dir= "C:\support\spcount.txt"

if($server_dir)
{

      $folders = Get-ChildItem $server_dir
        $output = @()

    foreach($folder in $folders)
    {

       $fname = $folder.Name
       $fpath = $folder.FullName
       $fcount = Get-ChildItem $fpath | Measure-Object | Select-Object -Expand Count
       $obj = New-Object psobject -Property @{FolderName = $fname; FileCount = $fcount} | Format-List; 
       $output += $obj

    }
     #Output
       $output | Tee-Object -FilePath $export_dir | Format-list FileCount
}

我得到了积极的结果,它列出了备份目录中的所有子项,但是如果目录包含 600 个或更多文件,我需要过滤它以仅显示和输出文本格式。

有人可以帮帮我吗?

我也是相当新的powershell所以如果这个代码不是最好的请拉我,我永远也想学习。

谢谢!

【问题讨论】:

    标签: windows shell powershell directory backup


    【解决方案1】:

    我想我找到了问题所在。就是对象创建语句末尾的 Format-List 语句。它将新创建的对象通过Format-List 管道化,从而将其转换为其他对象。

    $obj = New-Object psobject -Property @{FolderName = $fname; FileCount = $fcount} | Format-List
    

    所以如果你去掉最后一点,你会得到你期望的对象

    $obj = New-Object psobject -Property @{FolderName = $fname; FileCount = $fcount}
    

    因此,当您使用where 语句进行过滤时,您实际上会有一个 FileCount 属性可供过滤。 我通过Get-Member 运行 $output 检测到它,这表明它不是具有预期属性的对象。

    所以基本上,这是您的代码,包括修复:

    if($server_dir)
    {
        # *** Added the -directory flag, cause we don't need those pesky files ***
        $folders = Get-ChildItem $server_dir -directory
        $output = @()
    
        foreach($folder in $folders)
        {
    
           $fname = $folder.Name
           $fpath = $folder.FullName
           $fcount = Get-ChildItem $fpath | Measure-Object | Select-Object -Expand Count
           # *** Format-List was dropped here to avoid losing the objects ***
           $obj = New-Object psobject -Property @{FolderName = $fname; FileCount = $fcount}
           $output += $obj
    
        }
    
        # *** And now the filter and we're done ***
        $output | where -Property FileCount -ge 600 | Tee-Object -FilePath $export_dir | Format-list FileCount
    }
    

    还要注意-directory 以仅获取带有get-childitem 的文件夹,以及-ge 600g 大于或equal)而不是-gt 599这一点更明显。

    请记住,Format-* 语句实际上转换了通过它们传递的数据。因此,您应该只使用管道末端的那些在屏幕上显示数据或将其转储到文件中。 不要使用它来转换您以后仍要使用的数据。

    【讨论】:

    • 你先生,太棒了。我感觉它是 Format-List 运算符,我希望你能原谅我,因为我只做了几个月,哈哈。感谢 n3wjack,我真的很感激,我现在​​知道在哪里适合使用我的 Format-List 运算符。
    【解决方案2】:

    因此,简而言之,您可以执行类似的操作来获取该信息。

    Get-ChildItem C:\temp -Directory | 
        Select Name,@{Label="Count";Expression={(Get-Childitem $_ -file -Recurse).Count}} | 
        Where-Object{$_.Count -lt 10}
    

    让我们看看我们是否可以将其合并到您的代码中。您的if 声明也毫无意义。您的变量包含一个非空\非零长度字符串,因此它始终为真。如果我想象的目录存在,你希望它工作。

    $server_dir= "D:\backup"
    $export_dir= "C:\support\spcount.txt"
    
    if(Test-Path $server_dir){
        Get-ChildItem C:\temp -Directory | 
            Select Name,@{Label="Count";Expression={(Get-Childitem $_ -file -Recurse).Count}} | 
            Where-Object{$_.Count -lt 10} |
            ConvertTo-Csv | Tee -File $export_dir | ConvertFrom-Csv  
    } Else {
        Write-Warning "$server_dir does not exist."
    }
    

    请稍等片刻,将其与Tee 一起归档和筛选。

    【讨论】:

    • 嗨,马特,感谢您的帮助。看起来比较运算符是阻止我获得结果的关键因素。 Where-Object{$_.Count -lt 10} 带回 0 个结果,但是当我将其更改为 -ge 600 或 -gt 599 时,我什么也得不到...
    • @KieranGroome 我的代码需要 3.0,这可能是一个因素。你的 PowerShell 版本是什么?如果删除带有 where 子句的行,你会得到结果
    • 我正在一个 2012 R2 服务器上测试这个,默认情况下它当前具有版本 4 的 powershell。如果我禁用第 7 行 where 子句,它会在格式化表中返回结果,但是计数是 0,就好像 Get-ChildItem.Count 字符串没有返回值一样。
    • 很好奇。好的,当我开始工作时,我将使用我的 2012 年服务器进行测试
    【解决方案3】:

    我看到了两种方法来做到这一点。

    像这样在你的输出中过滤它:

    $output | where -property FileCount -gt 599 | # ... your code to write to the output
    

    或者如果不符合条件则不存入输出数组:

    if ($fcount -gt 599) {
       $obj = New-Object psobject -Property @{FolderName = $fname; FileCount = $fcount} | Format-List;
       $output += obj
    }
    

    【讨论】:

    • 嘿 n3wjack,感谢您的帮助。看起来比较运算符是阻止我获得结果的关键因素。 where -property FileCount -gt 599 | 带回 0 个结果,以及:if ($fcount -gt 599) { 也不给我。我想我的格式可能是:$obj= New-Object psobject -Property @{FolderName = $fname; FileCount = $fcount} | Format-List; $output+= $obj 可能不正确,因为我也无法成功导出到 CSV,只有纯文本和列标题无法正确导出。
    • 难道 $fcount 不是数字而是对象或字符串?我假设它是一个数字,但如果不是这种情况, -gt 当然会进行不同的比较。您可以使用$fcount | get-member 找出类型是什么。它应该说 System.Int32 一个数字。
    • $fcount 上的 Get-Member 结果显示为System.Int32奇怪
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 2018-09-08
    • 2019-02-06
    • 1970-01-01
    • 2013-04-11
    相关资源
    最近更新 更多