Como obter cinco arquivos com mais linhas no diretório atual da maneira mais simples?

Jan 09 2021

Existe um comando shell no capítulo "programação transformacional" de "O programador pragmático".

Sua função é listar os cinco arquivos com mais linhas no diretório atual.

$ 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

Estou tentando fazer a mesma coisa com o PowerShell, mas parece muito prolixo

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

Acredito que haverá uma maneira mais simples, mas não consigo pensar nisso.

Como obter arquivos com a maioria das linhas no diretório atual da maneira mais simples usando o PowerShell?

Obviamente, você não precisa usar abreviações e aliases personalizados para diminuir o comprimento. Embora pareça mais conciso, ele perde a legibilidade.

Respostas

2 iRon Jan 09 2021 at 20:05
Get-Content * | Group-Object PSChildName | Select-Object Count, Name |
    Sort-Object Count | Select-Object -Last 5
1 if_ok_button Jan 10 2021 at 09:02

Finalmente encontrei minha própria resposta satisfatória!

Usou 3 operadores de pipeline, shell usou 5!

Além do mais, o que obtemos é o objeto, que pode ser usado para operações mais extensíveis.

Me sinto melhor que shell de linux.

dir -file | sort {($_ | gc).Length} | select -l 5
pwnosh Jan 09 2021 at 16:42

Tente File.ReadLines com Linq ou File.ReadAllLines com propriedade Count.

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
Theo Jan 09 2021 at 18:35

Uma abordagem rápida seria usar 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