递归计算子文件夹中的文件

时间:2014-08-26 13:06:06

标签: powershell recursion

我正在尝试计算目录中所有子文件夹中的文件,并将它们显示在列表中。

例如以下的污垢:

TEST
    /VOL01
        file.txt
        file.pic
    /VOL02
        /VOL0201
            file.nu
            /VOL020101
                file.jpg
                file.erp
                file.gif
    /VOL03
        /VOL0301
            file.org

应该作为输出:

PS> DirX C:\TEST

Directory              Count
----------------------------
VOL01                      2
VOL02                      0
VOL02/VOL0201              1
VOL02/VOL0201/VOL020101    3
VOL03                      0
VOL03/VOL0301              1

我从以下开始:

Function DirX($directory)
{
    foreach ($file in Get-ChildItem $directory -Recurse)
    {
        Write-Host $file
    }
}

现在我有一个问题:为什么我的功能没有递归?

6 个答案:

答案 0 :(得分:23)

这样的事情应该有效:

dir -recurse |  ?{ $_.PSIsContainer } | %{ Write-Host $_.FullName (dir $_.FullName | Measure-Object).Count }
  • dir -recurse列出当前目录下的所有文件,并将结果(|)列为
  • ?{ $_.PSIsContainer }仅过滤目录,然后再次将结果列表重新连接到
  • %{ Write-Host $_.FullName (dir $_.FullName | Measure-Object).Count }这是一个foreach循环,对于列表的每个成员($ _)显示全名和以下表达式的结果
  • (dir $_.FullName | Measure-Object).Count,提供$ _。FullName路径下的文件列表,并通过Measure-Object

  • 计算成员数
  • ?{ ... }是Where-Object

  • 的别名
  • %{ ... }是foreach的别名

答案 1 :(得分:6)

与David的解决方案类似,这将在Powershell v3.0中有效,并且在有人不熟悉的情况下不使用别名

Get-ChildItem -Directory | ForEach-Object { Write-Host $_.FullName $(Get-ChildItem $_ | Measure-Object).Count}

回答补充

根据关于保持功能和循环结构的注释,我提供以下内容。 注意我不宽恕这个解决方案,因为它很难看并且内置的cmdlet处理得非常好。但是我想帮忙,所以这里是你的脚本的更新。

Function DirX($directory)
{
    $output = @{}

    foreach ($singleDirectory in (Get-ChildItem $directory -Recurse -Directory))
    {
        $count = 0 
        foreach($singleFile in Get-ChildItem $singleDirectory.FullName)
        {
            $count++
        }
        $output.Add($singleDirectory.FullName,$count)
    }

    $output | Out-String
}

对于每个$singleDirectory计数所有使用$count的文件(在下一个子循环之前重置)并将每个查找输出到哈希表。最后输出哈希表作为字符串。在您的问题中,您看起来想要一个对象输出而不是直接文本。

答案 2 :(得分:3)

嗯,就这样做,整个Get-ChildItem cmdlet需要在foreach循环开始迭代之前完成。你确定你等了足够长的时间吗?如果你针对非常大的目录(比如C :)运行它,那将需要相当长的时间。

编辑:看到你之前问过一种方法,让你的功能按照你的要求去做,你走了。

Function DirX($directory)
{
    foreach ($file in Get-ChildItem $directory -Recurse -Directory )
    {
        [pscustomobject] @{
        'Directory' = $File.FullName
        'Count' = (GCI $File.FullName -Recurse).Count
        }
    }
}
DirX D:\

foreach循环只获取目录,因为这是我们所关心的,然后在循环内部为每次迭代创建一个自定义对象,其中包含文件夹的完整路径和内部项目的计数。文件夹中。

此外,请注意,这仅适用于PowerShell 3.0或更高版本,因为2.0中不存在-directory参数

答案 3 :(得分:0)

我的版本 - 稍微清洁并将内容转储到文件

原创 - Recursively count files in subfolders

第二部分 - Count items in a folder with PowerShell

        <div class="col-md-6">
            <h3>Sign Up</h3>
            <!-- Use a regular HTML route instead of Laravel's own -->
            <form action="/signup" method="POST">
                <div class="form-group">
                    <label for="email">Your Email</label>
                    <input type="form-control" type="text" name="email" id="email">
                </div>
                <div class="form-group">
                    <label for="first_name">Your First Name</label>
                    <input type="form-control" type="text" name="first_name" id="first_name">
                </div>
                <div class="form-group">
                    <label for="password">Your Password</label>
                    <input type="form-control" type="password" name="password" id="password">
                </div>
                <!-- Changed the submit button to input element instead of button -->
                <input type="submit" class="btn btn-primary" value="Submit">
                <input type="hidden" name="_token" value="{{Session::token()}}">
            </form>
        </div>

答案 4 :(得分:0)

我稍微修改了David Brabant的解决方案,所以我可以评估结果:

$FileCounter=gci "$BaseDir" -recurse |  ?{ $_.PSIsContainer } | %{ (gci "$($_.FullName)" | Measure-Object).Count }
Write-Host "File Count=$FileCounter"
If($FileCounter -gt 0) {
  ... take some action...
}

答案 5 :(得分:0)

Get-ChildItem $rootFolder `
    -Recurse -Directory | 
        Select-Object `
            FullName, `
            @{Name="FileCount";Expression={(Get-ChildItem $_ -File | 
        Measure-Object).Count }}