Recursively count files in subfolders

后端 未结 6 1832
耶瑟儿~
耶瑟儿~ 2020-12-29 10:08

I am trying to count the files in all subfolders in a directory and display them in a list.

For instance the following dirtree:

TEST
    /VOL01
              


        
相关标签:
6条回答
  • 2020-12-29 10:24

    My version - slightly cleaner and dumps content to a file

    Original - Recursively count files in subfolders

    Second Component - Count items in a folder with PowerShell

    $FOLDER_ROOT = "F:\"
    $OUTPUT_LOCATION = "F:DLS\OUT.txt"
    Function DirX($directory)
    {
        Remove-Item $OUTPUT_LOCATION
    
        foreach ($singleDirectory in (Get-ChildItem $directory -Recurse -Directory))
        {
            $count = Get-ChildItem $singleDirectory.FullName -File | Measure-Object | %{$_.Count}
            $summary = $singleDirectory.FullName+"    "+$count+"    "+$singleDirectory.LastAccessTime
            Add-Content $OUTPUT_LOCATION $summary
        }
    }
    DirX($FOLDER_ROOT)
    
    0 讨论(0)
  • 2020-12-29 10:28

    Similar to David's solution this will work in Powershell v3.0 and does not uses aliases in case someone is not familiar with them

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

    Answer Supplement

    Based on a comment about keeping with your function and loop structure i provide the following. Note: I do not condone this solution as it is ugly and the built in cmdlets handle this very well. However I like to help so here is an update of your script.

    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
    }
    

    For each $singleDirectory count all files using $count ( which gets reset before the next sub loop ) and output each finding to a hash table. At the end output the hashtable as a string. In your question you looked like you wanted an object output instead of straight text.

    0 讨论(0)
  • 2020-12-29 10:35
    Get-ChildItem $rootFolder `
        -Recurse -Directory | 
            Select-Object `
                FullName, `
                @{Name="FileCount";Expression={(Get-ChildItem $_ -File | 
            Measure-Object).Count }} 
    
    0 讨论(0)
  • 2020-12-29 10:41

    I modified David Brabant's solution just a bit so I could evaluate the result:

    $FileCounter=gci "$BaseDir" -recurse |  ?{ $_.PSIsContainer } | %{ (gci "$($_.FullName)" | Measure-Object).Count }
    Write-Host "File Count=$FileCounter"
    If($FileCounter -gt 0) {
      ... take some action...
    }
    
    0 讨论(0)
  • 2020-12-29 10:42

    Something like this should work:

    dir -recurse |  ?{ $_.PSIsContainer } | %{ Write-Host $_.FullName (dir $_.FullName | Measure-Object).Count }
    
    • dir -recurse lists all files under current directory and pipes (|) the result to
    • ?{ $_.PSIsContainer } which filters directories only then pipes again the resulting list to
    • %{ Write-Host $_.FullName (dir $_.FullName | Measure-Object).Count } which is a foreach loop that, for each member of the list ($_) displays the full name and the result of the following expression
    • (dir $_.FullName | Measure-Object).Count which provides a list of files under the $_.FullName path and counts members through Measure-Object

    • ?{ ... } is an alias for Where-Object

    • %{ ... } is an alias for foreach
    0 讨论(0)
  • 2020-12-29 10:44

    Well, the way you are doing it the entire Get-ChildItem cmdlet needs to complete before the foreach loop can begin iterating. Are you sure you're waiting long enough? If you run that against very large directories (like C:) it is going to take a pretty long time.

    Edit: saw you asked earlier for a way to make your function do what you are asking, here you go.

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

    The foreach loop only get's directories since that is all we care about, then inside of the loop a custom object is created for each iteration with the full path of the folder and the count of the items inside of the folder.

    Also, please note that this will only work in PowerShell 3.0 or newer, since the -directory parameter did not exist in 2.0

    0 讨论(0)
提交回复
热议问题