对此进行管道传递和过滤的最佳方法是什么?

时间:2019-07-27 00:06:30

标签: powershell pipeline

我只是想从Get-ChildItem`中过滤信息的名称。

$folders = Get-ChildItem C:\Users

$folders.Name -like '*test*'

除了写这两行,最好的方法是什么?

.Name这个术语叫什么?

3 个答案:

答案 0 :(得分:2)

名称是一个属性。有很多方法:

get-childitem c:\users\*test*
get-childitem c:\users *test* # filter
get-childitem c:\users | where name -like *test*
get-childitem c:\users | where name -match test
(get-childitem c:\users).name -like '*test*' # doesn't stream as well

答案 1 :(得分:1)

在您的示例中,更好的解决方案是

Get-ChildItem C:\Users -filter "*test*"

因为过滤器直接位于第一个命令中,而不是位于管道之后,所以性能会更好

如果只想找到文件或只想找到目录,请不要忘记在Get-ChildItem命令中使用-file vs -directory;)

答案 2 :(得分:1)

在回答问题之前,我认为定义为什么使用管道非常重要。
为此,我可以看到两个主要原因:

  1. 提高性能
  2. 减少内存使用量

尽管第一个原因(性能)在大多数情况下是使用管道的背后动力,但这并不总是最快的方法,将所有内容简单地加载到内存中并比对其执行操作在很多情况下要快得多使用管道。

那么,什么时候可以更快地使用管道?
如果输入源或输出目标的速度较慢,则管道通常会更快,因为您使用等待时间(直到接收或接受下一个项目)才可以继续工作并处理剩余的剩余项目。

以您的问题为例:
假设您要处理 1000 个项目(文件),并且需要 10毫秒来检索一个项目(文件从磁盘)和 5毫秒过滤它。如果您不使用管道,则需要1000 * 10 + 1000 * 5 = 15000毫秒来处理,如果您使用管道,则仅需1000 * 10 + 5 = 10005毫秒进行处理,因为您已经在等待接收每个下一个项目的同时已处理(过滤并释放)其他 999 项。
注意:这可能不是一个好例子,因为文件可能已缓存并且可以非常快速地交付,但是如果它们来自远程位置,则情况会不同。

(考虑到这一点,我想更改问题:)

什么是不是管道传输和过滤的好方法?

实际上有两种主要的PowerShell编程技术会阻塞管道:

  1. 将管道分配给变量时。
    就像您的问题一样: $folders = Get-ChildItem C:\Users
  2. 使用括号。
    (Get-ChildItem C:\Users) | ... (实际上是您进行的匿名分配。)

换句话说,对于最好的流水线和过滤方法?
使用竖线字符(|),并尝试避免使用任何赋值或括号,因为这会将管道中的所有项目堆积到内存中。