Comment faire quoi faire la tête, la queue, plus, moins, sed dans Powershell? [fermé]

110

Sur les fenêtres, en utilisant Powershell, quelles sont les commandes équivalentes à linux de head, tail, more, lesset sed?

Yue Zhang
la source
Le fichier journal est trop volumineux, environ plusieurs Mo. C'est trop difficile à afficher par notepad.exe.
Yue Zhang
Si vous utilisez notepadcomme base, je suggérerais de regarder des éditeurs de texte alternatifs, il existe de nombreuses alternatives (gratuites et payantes). Tous sont supérieurs au bloc-notes (bien que ce ne soit pas vraiment un défi).
Richard
duplication possible de PowerShell vs Unix Shells
manojlds
Je traite de gros fichiers et j'utilise / installe Vim qui s'avère beaucoup plus rapide que tout autre outil que j'ai utilisé.
sfanjoy

Réponses:

176

Get-Content(alias:) gcest votre option habituelle pour lire un fichier texte. Vous pouvez ensuite filtrer davantage:

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

Cela fonctionne assez bien pour les petits fichiers, les plus gros (plus de quelques Mio) sont probablement un peu lents.

Les extensions de communauté PowerShell incluent des applets de commande pour les fichiers spécialisés (par exemple, Get-FileTail).

Joey
la source
3
Holy cow, cela maximise mon processeur pour faire un -last 2CSV de 1 Go. Boisson chaude: ☕
mlissner
9
@mlissner: si vous utilisez PowerShell v3, vous pouvez utiliser à la Get-Content -Tail 2place. C'est nettement plus rapide.
Joey
gc log.txt | %{ $_ -replace '\d+', '($0)' } # sedce n'est pas vraiment l'outil sed car il ne remet pas de contenu. Il a besoin de Set-Content.
Artyom
3
@Neil, -Lastest lent pour la même raison awkserait lent pour la même tâche: il doit d'abord consommer complètement le flux. Voilà pourquoi Get-Content -Tailexiste. Et il n'y a pas headparce qu'il ne rentre pas dans les conventions de dénomination et que son objectif est déjà atteint Select-Item.
Joey
3
@neil @joey Ils ont un alias pour -head. Voir ma réponse stackoverflow.com/a/41626586/1081043
wisbucky
53

Voici les moyens intégrés de faire headet tail. N'utilisez pas de tuyaux, car si vous avez un gros fichier, il sera extrêmement lent. L'utilisation de ces options intégrées sera extrêmement rapide, même pour les fichiers volumineux.

gc log.txt -head 10 
gc log.txt -tail 10
gc log.txt -tail 10 -wait # equivalent to tail -f
wisbucky
la source
mais le commentaire de Joey semble indiquer exactement le contraire! comment savoir à qui faire confiance ou quelle méthode (intégrée) est la plus efficace?
NH.
2
@NH Ma réponse est en accord avec le commentaire de Joey. Son commentaire dit "-La dernière est lente ... C'est pourquoi Get-Content -Tail existe." | select -lastutilise des tuyaux. J'utilise -tailsans tuyaux. Mais si jamais vous trouvez deux réponses contradictoires, vous pourriez probablement faire confiance à la personne qui a une réputation beaucoup plus élevée. En outre, vous pouvez simplement essayer les deux méthodes sur un gros fichier. Ce sera très évident sur un gros fichier.
wisbucky
Je l'ai. Désolé, j'ai dû être confus la première fois que j'ai lu les messages.
NH.
8

more.exeexiste sous Windows, les ports de lesssont faciles à trouver (et les extensions de communauté PowerShell , PSCX, en incluent un).

PowerShell ne fournit pas vraiment d'alternative à des programmes séparés pour l'un ou l'autre, mais pour les données structurées, cela Out-Gridpeut être utile.

Headet Tailpeuvent tous deux être émulés en Select-Objectutilisant respectivement les paramètres -Firstet -Last.

Sedles fonctions sont toutes disponibles mais structurées assez différemment. Les options de filtrage sont disponibles dans Where-Object(ou via Foreach-Objectet dans certains états pour les plages). D'autres opérations de transformation peuvent être effectuées avec Select-Objectet Foreach-Object.

Cependant, lorsque PowerShell passe des objets (.NET) - avec toute leur structure typée, par exemple. les dates restent des DateTimeinstances - plutôt que de simples chaînes, que chaque commande doit analyser elle-même, une grande partie sedet d'autres programmes de ce type sont redondants.

Richard
la source
Brillant. gc ne semble pas prendre en charge l'entrée de tube. quand je veux filtrer la sortie d'une commande, j'utilise "... exe ... | select-object -first 20 | select-object -last 1"
A117
2

"-TotalCount" dans cet exemple répond exactement comme "-head". Vous devez utiliser -TotalCount ou -head pour exécuter la commande comme ça. Mais -TotalCount est trompeur - cela ne fonctionne pas en vous donnant VRAIMENT aucun compte ...

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

Le script ci-dessus, testé dans PS 5.1 est la même réponse que ci-dessous ...

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

Alors utilisez déjà '-head 25 "!

Patrick Burwell
la source
Salut @Patrick, bienvenue dans Stack Overflow! Merci d'avoir essayé de répondre à cette question, pourriez-vous s'il vous plaît fournir une explication plus détaillée? Il n'est pas clair si vous essayez d'offrir une solution ou simplement d'ajouter un commentaire sur le problème.
Rocío García Luque
C'était un commentaire et aussi une frustration. '-TotalCount "ne fait rien" -Head "ne fait pas déjà. Alors est-ce que quelqu'un sait maintenant comment obtenir un TotalCount?
Patrick Burwell
Relisez-le ... j'ai ajouté à la réponse et clarifié ce qui fonctionne ...
Patrick Burwell
1

Si vous avez besoin d'interroger des fichiers journaux volumineux (ou petits) sous Windows, le meilleur outil que j'ai trouvé est le logiciel gratuit Log Parser 2.2 de Microsoft . Vous pouvez l'appeler depuis PowerShell si vous le souhaitez et il fera tout le gros du travail pour vous, et très rapidement aussi.

Ce qui serait cool
la source
merci quand même, mon environnement est Win2k8R2 qui n'est pas dans la configuration système requise de Log Parser2.2
Yue Zhang
0

J'ai de meilleures solutions:

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
la source
-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

Vous n'obtenez pas toutes les erreurs avec le code pushpop BTW, votre code ne fonctionne qu'avec l'option "sed". Tout le reste ignore tout sauf gc et path.

Patrick Burwell
la source