如何在Powershell中执行头,尾,多,少,sed的操作?[关闭]


109

在Windows上,使用PowerShell,什么是等效命令到Linux的headtailmorelesssed


日志文件太大,大约几个兆字节。用notepad.exe很难查看。
张跃

如果您notepad以自己为基础,我建议您考虑使用替代文本编辑器,这里有很多(免费和付费)替代方案。所有这些都比记事本优越(尽管这不是一个很大的挑战)。
理查德


我处理大文件,并且使用/安装Vim证明比我使用的任何其他工具快得多。
sfanjoy

Answers:


174

Get-Content(别名:)gc是您阅读文本文件的常用选项。然后,您可以进一步过滤:

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

这对于小文件已经足够好了,较大的文件(超过几个MiB)可能会有点慢。

PowerShell的社区扩展包括专门文件的东西(如GET-FileTail)某些cmdlet。


3
天哪,这使我的CPU用尽了-last 2一个1GB CSV。热饮:☕–
mlissner

9
@mlissner:如果您使用的是PowerShell v3,则可以Get-Content -Tail 2改用。那肯定更快。
乔伊

gc log.txt | %{ $_ -replace '\d+', '($0)' } # sed这实际上并不完全是sed工具,因为它不会放回内容。它需要Set-Content。
Artyom 2015年

3
@Neil,-Last由于相同的原因awk而变慢,对于相同的任务将变慢:它必须首先完全消耗流。这就是为什么Get-Content -Tail存在。也没有,head因为它不符合命名约定,并且的目的已经由满足Select-Item
乔伊,

3
@neil @joey他们有个别名-head。见我的答案stackoverflow.com/a/41626586/1081043
wisbucky

52

这是执行head和的内置方法tail。不要使用管道,因为如果文件很大,它将非常慢。即使对于大型文件,使用这些内置选项也将非常快。

gc log.txt -head 10 
gc log.txt -tail 10
gc log.txt -tail 10 -wait # equivalent to tail -f

乔伊(Joey)的评论似乎表明完全相反!我如何知道信任谁或哪种(内置)方法最有效?
NH。

2
@NH我的回答与Joey的评论一致。他的评论说:“-最后很慢...这就是为什么存在Get-Content -Tail的原因。” | select -last使用管道。我-tail没有管道。但是,如果您确实找到两个相互矛盾的答案,则您可能会相信信誉较高的人。另外,您可以简单地在大文件上尝试这两种方法。在大文件上这将是非常明显的。
wisbucky

得到它了。抱歉,我第一次阅读帖子时一定很困惑。
NH。

8

more.exe在Windows上存在,less很容易找到的端口(PowerShell Community Extensions PSCX包括其中之一)。

PowerShell确实没有为单独的程序提供任何替代方案,但是对于结构化数据Out-Grid可能会有所帮助。

Head并且Tail都可以分别Select-Object使用-First-Last参数进行仿真。

Sed功能都可用,但结构却大不相同。过滤选项可用Where-Object(或通过Foreach-Object范围的某种状态)。其他转换操作可以使用Select-Object和完成Foreach-Object

但是,随着PowerShell通过(.NET)对象–具有其所有类型结构,例如。date仍然是DateTime实例–不仅仅是每个命令都需要解析的字符串,很多sed此类程序都是多余的。


辉煌。gc似乎不支持管道输入。当我想过滤命令的输出时,我使用的是“ ... exe ... |选择对象-前20 |选择对象-后1”
A117

2

在这种情况下,“-TotalCount”的响应与“ -head”完全相同。您必须使用-TotalCount或-head来运行类似的命令。但是-TotalCount具有误导性-实际上无法为您提供任何计数...

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

在PS 5.1中测试的上述脚本是如下的SAME响应...

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

因此,只需使用“ -head 25”!


嗨@Patrick,欢迎来到Stack Overflow!感谢您尝试回答这个问题,能否请您提供更详细的说明?目前尚不清楚您是要提供解决方案还是只是对问题添加一些评论。
罗西奥·加西亚·卢克

这是一种评论,也是一种沮丧。“ -TotalCount”什么都不做“ -Head”还没有做,所以有人知道如何获取TotalCount吗?
Patrick Burwell

再读一遍...我添加到答案中,并阐明了有效的方法...
Patrick Burwell,

1

如果您需要在Windows上查询大型(或小型)日志文件,我发现的最好的工具是Microsoft的免费Log Parser 2.2。您可以根据需要从PowerShell调用它,它将为您完成所有繁重的工作,而且速度也非常快。


无论如何,我的环境是Win2k8R2,它不在Log Parser2.2的系统要求中
Yue Zhang

0

我有一些更好的解决方案:

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

-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

推送代码BTW并不能解决所有错误,您的代码只能与“ sed”选项一起使用。除了gc和path,其余所有内容都忽略任何其他内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.