Como fazer o que head, tail, more, less, sed fazem no Powershell? [fechadas]

109

No Windows, usando o PowerShell, quais são os comandos equivalentes para linux do head, tail, more, lesse sed?

Yue Zhang
fonte
o arquivo de log é muito grande, cerca de vários MBytes. É muito difícil visualizar pelo notepad.exe.
Yue Zhang
Se você estiver usando notepadcomo base, sugiro que você procure editores de texto alternativos, pois há muitas alternativas (gratuitas e pagas). Todos são superiores ao bloco de notas (embora isso não seja um grande desafio).
Richard,
possível duplicata de PowerShell vs. Unix Shells
manojlds
Eu lido com arquivos grandes e uso / instalo o Vim, o que é muito mais rápido do que qualquer outra ferramenta que usei.
sfanjoy

Respostas:

174

Get-Content(alias:) gcé sua opção usual para ler um arquivo de texto. Você pode filtrar ainda mais:

gc log.txt | select -first 10 # head
gc -TotalCount 10 log.txt     # also head
gc log.txt | select -last 10  # tail
gc -Tail 10 log.txt           # also tail (since PSv3), also much faster than above option
gc log.txt | more             # or less if you have it installed
gc log.txt | %{ $_ -replace '\d+', '($0)' }         # sed

Isso funciona bem o suficiente para arquivos pequenos, os maiores (mais do que alguns MiB) são provavelmente um pouco lentos.

As extensões da comunidade do PowerShell incluem alguns cmdlets para arquivos especializados (por exemplo, Get-FileTail).

Joey
fonte
3
Caramba, isso está maximizando minha CPU para fazer um -last 2em um CSV de 1 GB. Bebida quente: ☕
mlissner
9
@mlissner: Se você estiver no PowerShell v3, poderá usar em seu Get-Content -Tail 2lugar. Isso é definitivamente mais rápido.
Joey de
gc log.txt | %{ $_ -replace '\d+', '($0)' } # sedisso não é totalmente a ferramenta sed, uma vez que não coloca o conteúdo de volta. Ele precisa de Set-Content.
Artyom de
3
@Neil, -Lasté lento pela mesma razão awkque seria lento para a mesma tarefa: primeiro tem que consumir o stream completamente. É por isso que Get-Content -Tailexiste. E não há headporque não se encaixa nas convenções de nomenclatura e seu propósito já é servido por Select-Item.
Joey
3
@neil @joey Eles têm um alias para -head. Veja minha resposta stackoverflow.com/a/41626586/1081043
wisbucky
52

Aqui estão as maneiras integradas de fazer heade tail. Não use pipes, pois se você tiver um arquivo grande, será extremamente lento. Usar essas opções integradas será extremamente rápido, mesmo para arquivos grandes.

gc log.txt -head 10 
gc log.txt -tail 10
gc log.txt -tail 10 -wait # equivalent to tail -f
wisbucky
fonte
mas o comentário de Joey parece indicar exatamente o oposto! como faço para saber em quem confiar ou qual método (integrado) é mais eficiente?
NH.
2
@NH Minha resposta está de acordo com o comentário de Joey. Seu comentário diz "-Last é lento ... É por isso que Get-Content -Tail existe." | select -lastusa tubos. Estou usando -tailsem canos. Mas se você encontrar duas respostas conflitantes, provavelmente poderá confiar na pessoa com uma reputação muito mais elevada. Além disso, você pode simplesmente tentar os dois métodos em um arquivo grande. Será muito óbvio em um arquivo grande.
wisbucky
Entendi. Desculpe, devo ter ficado confuso na primeira vez que li os posts.
NH.
8

more.exeexiste no Windows, as portas de lesssão facilmente encontradas (e as extensões da comunidade do PowerShell , PSCX, incluem uma).

O PowerShell realmente não oferece nenhuma alternativa para separar programas para nenhum dos dois, mas para dados estruturados Out-Gridpode ser útil.

Head e Tail podem ser emulados com o Select-Objectuso dos parâmetros -Firste -Lastrespectivamente.

Sedtodas as funções estão disponíveis, mas estruturadas de forma bastante diferente. As opções de filtragem estão disponíveis emWhere-Object (ou via Foreach-Objecte algum estado para intervalos). Outras operações de transformação podem ser feitas com Select-Objecte Foreach-Object.

No entanto, à medida que o PowerShell passa (.NET) objetos - com toda a sua estrutura tipada, por exemplo. as datas permanecem como DateTimeinstâncias - em vez de apenas strings, que cada comando precisa para analisar a si mesmo, muitos de sedoutros programas semelhantes são redundantes.

Richard
fonte
Brilhante. gc não parece suportar entrada de tubo. quando quero filtrar a saída de um comando, estou usando "... exe ... | select-object -first 20 | select-object -last 1"
A117
2

"-TotalCount" nesta instância responde exatamente como "-head". Você tem que usar -TotalCount ou -head para executar o comando assim. Mas -TotalCount é enganoso - ele não funciona, REALMENTE, dando-lhe NENHUMA contagem ...

gc -TotalCount 25 C:\scripts\logs\robocopy_report.txt

O script acima, testado em PS 5.1, tem a MESMA resposta abaixo ...

gc -head 25 C:\scripts\logs\robocopy_report.txt

Então use '-head 25 "já!

Patrick Burwell
fonte
Olá @Patrick, bem-vindo ao Stack Overflow! Obrigado por tentar responder a esta pergunta, poderia fornecer uma explicação mais detalhada? Não está claro se você está tentando oferecer uma solução ou apenas adicionar algum comentário sobre o problema.
Rocío García Luque
Foi um comentário e também uma frustração. '-TotalCount "não faz nada" -Head "ainda não faz. Alguém sabe como obter um TotalCount?
Patrick Burwell
Leia novamente ... acrescentei à resposta e esclareci o que funciona ...
Patrick Burwell
1

Se você precisar consultar arquivos de log grandes (ou pequenos) no Windows, a melhor ferramenta que encontrei é o Log Parser 2.2 gratuito da Microsoft . Você pode chamá-lo do PowerShell se quiser e ele fará todo o trabalho pesado para você, e muito rápido também.

O que seria legal
fonte
obrigado de qualquer maneira, meu ambiente é Win2k8R2 que não está nos requisitos de sistema do Log Parser2.2
Yue Zhang
0

Eu tenho algumas soluções melhores:

gc log.txt -ReadCount 5 | %{$_;throw "pipeline end!"} # head
gc log.txt | %{$num=0;}{$num++;"$num $_"}             # cat -n
gc log.txt | %{$num=0;}{$num++; if($num -gt 2 -and $num -lt 7){"$num $_"}} # sed
Yue Zhang
fonte
-1
$Push_Pop = $ErrorActionPreference #Suppresses errors
$ErrorActionPreference = SilentlyContinue #Suppresses errors
#Script
    #gc .\output\*.csv -ReadCount 5 | %{$_;throw "pipeline end!"} # head
    #gc .\output\*.csv | %{$num=0;}{$num++;"$num $_"}             # cat -n
    gc .\output\*.csv | %{$num=0;}{$num++; if($num -gt 2 -and $num -lt 7){"$num $_"}} # sed
#End Script 
$ErrorActionPreference = $Push_Pop #Suppresses errors

Você não obtém todos os erros com o código pushpop BTW, seu código só funciona com a opção "sed". Todo o resto ignora qualquer coisa, exceto gc e path.

Patrick Burwell
fonte