我已经编写了一个简单的PowerShell过滤器,如果当前对象的日期在指定的开始和结束日期之间,则将其推送到管道中。从管道中下来的对象总是按日期升序排列的,所以只要日期超过指定的结束日期,我就知道我的工作已经完成了,我想告诉管道上游命令可以放弃他们的工作,这样管道就可以完成它的工作。我正在阅读一些非常大的日志文件,我经常只想检查日志的一部分。我很确定这是不可能的,但我想问一下。
我已经编写了一个简单的PowerShell过滤器,如果当前对象的日期在指定的开始和结束日期之间,则将其推送到管道中。从管道中下来的对象总是按日期升序排列的,所以只要日期超过指定的结束日期,我就知道我的工作已经完成了,我想告诉管道上游命令可以放弃他们的工作,这样管道就可以完成它的工作。我正在阅读一些非常大的日志文件,我经常只想检查日志的一部分。我很确定这是不可能的,但我想问一下。
8条答案
按热度按时间e7arh2l61#
可以使用任何会中断外部循环或完全停止脚本执行(如抛出异常)的东西来中断管道。解决方案是将管道 Package 在一个循环中,如果需要停止管道,可以中断该循环。
例如,下面的代码将返回管道中的第一项,然后通过中断外部do-while循环来中断管道:
这个功能可以 Package 成这样的函数,其中最后一行完成与上面相同的事情:
ghg1uchk2#
无法从下游命令停止上游命令。它将继续过滤掉不符合条件的对象,但第一个命令将处理它设置要处理的所有内容。
解决方法是在上游cmdlet或function/filter上执行更多筛选。使用日志文件会使它变得有点复杂,但是使用Select-String和正则表达式来过滤掉不需要的日期可能对您有用。
除非你知道你想要多少行和从哪里开始,否则整个文件将被读取以检查模式。
cwtwac6a3#
下面是
Stop-Pipeline
cmdlet(需要PS v3+)的一个不完美的实现,它是从this answer改编而来的:警告:我不完全理解它是如何工作的,尽管它从根本上利用了
Select -First
过早停止管道的能力(PS v3+)。然而,在这种情况下,Select -First
终止管道的方式有一个关键的区别:*下游 * cmdlet(管道中 * 稍后 * 的命令)没有机会运行其end
块。因此,聚合cmdlet(必须接收 * 所有 * 输入才能产生输出的cmdlet,如
Sort-Object
、Group-Object
和Measure-Object
)如果稍后放置在同一管道中,将不会产生输出;例如:背景信息,可能导致更好的解决方案:
多亏了PetSerAl,我的answer here展示了如何生成
Select-Object -First
在内部用来停止上游cmdlet的相同异常。但是,在那里,从 * 本身连接到要停止的管道 * 的cmdlet内部抛出异常,这里不是这种情况:
上面例子中使用的
Stop-Pipeline
* 没有 * 连接到应该停止的流水线(只有外围的ForEach-Object
(%
)块连接到了),所以问题是:如何在目标管道的上下文中引发异常?3lxsmp7m4#
结束管道时可以引发异常。
或
看看这篇关于如何终止管道的文章:https://web.archive.org/web/20160829015320/http://powershell.com/cs/blogs/tobias/archive/2010/01/01/cancelling-a-pipeline.aspx
bqujaahr5#
不确定您的确切需求,但可能值得您花时间研究一下Log Parser,看看是否可以在数据到达管道之前使用查询来过滤数据。
6psbrbz96#
如果你愿意使用非公共成员,这里是一种停止管道的方法。它模仿了
select-object
的功能。invoke-method
(别名im
)是一个调用非公共方法的函数。select-property
(别名selp
)是一个选择(类似于select-object)非公共属性的函数,但是如果只找到一个匹配的属性,它会自动像-ExpandProperty
一样工作。(我在工作中写了select-property
和invoke-method
,所以不能分享它们的源代码)。编辑:根据mklement 0的评论:
这里是一个link的Nivot墨水博客上的一个脚本上的“戳”模块,同样给予访问非公共成员。
至于其他评论,我在这一点上没有有意义的。这段代码只是模仿了
select-object
的反编译所揭示的内容。原始的MS注解(如果有的话)当然不在反编译中。坦率地说,我不知道函数使用的各种类型的目的。要达到这样的理解水平可能需要相当大的努力。我的建议是:拿到奥辛的戳模块调整代码以使用该模块。然后尝试一下。如果你喜欢它的工作方式,那么就使用它,不要担心它是如何工作的(这就是我所做的)。
注意:我没有深入研究过“poke”,但我猜它没有任何类似
-returnClosure
的东西。然而,添加应该很容易,因为这:wljmcqd87#
尝试这些过滤器,它们会强制管道在第一个对象或前n个元素后停止,并将其存储在变量中;你需要传递变量的名字,如果你不这样做,对象(s)被推出,但不能被分配给变量。
z4bn682m8#
另一种选择是在
switch
语句上使用-file
参数。使用-file
将一次读取一行文件,您可以使用break
立即退出,而无需阅读文件的其余部分。