How to get five files with most lines in the current directory by simplest way?

Viewed 118

There is such a shell command in the chapter "transformational programming" of "The Pragmatic Programmer".

Its function is to list the five files with the most lines in the current directory.

$ find . -type f | xargs wc -l | sort -n | tail -6 | head -5
     470 ./debug.pml
     470 ./test_to_build.pml
     487 ./dbc.pml
     719 ./domain_languages.pml
     727 ./dry.pml

I'm trying to do the same thing with PowerShell,But it seems too wordy

(Get-ChildItem .\ | ForEach-Object {$_ | Select-Object -Property 'Name', @{label = 'Lines'; expression = {($_ | Get-Content).Length}}} |Sort-Object -Property 'Lines')|Select-Object -Last 5

I believe there will be a simpler way, but I can't think of it.

How to get files with most lines in the current directory by simplest way using PowerShell?

Of course, you don't need to use custom aliases and abbreviations to shorten the length. Although it looks more concise, it loses readability.

4 Answers
Get-Content * | Group-Object PSChildName | Select-Object Count, Name |
    Sort-Object Count | Select-Object -Last 5

I finally found my own satisfactory answer!

Used 3 pipeline operators, shell used 5!

What's more, what we get is the object, which can be used for more extensible operations.

I feel better than shell of linux.

dir -file | sort {($_ | gc).Length} | select -l 5

Try either File.ReadLines with Linq or File.ReadAllLines with Count property.

File.ReadLines

Get-ChildItem .\ -File | 
    Select-Object -Property Name, @{n='Lines'; e= { 
            [System.Linq.Enumerable]::Count([System.IO.File]::ReadLines($_.FullName)) 
        } 
    } | Sort-Object -Property 'Lines' -Descending | Select-Object -First 5

File.ReadAllLines

Get-ChildItem .\ -File | 
    Select-Object -Property Name, @{n='Lines'; e= { 
            [System.IO.File]::ReadAllLines($_.FullName).Count 
        } 
    } | Sort-Object -Property 'Lines' -Descending | Select-Object -First 5

A fast approach would be to use switch -File:

$files = (Get-ChildItem -File ).FullName 
$result = foreach ($file in $files) {
    $lineCount = 0
    switch -File $file {
        default { $lineCount++ }
    }
    [PsCustomObject]@{
        File  = $file
        Lines = $lineCount
    }
}
$result | Sort-Object Lines | Select-Object -Last 5
Related