$files = Get-ChildItem $directory -Recurse | Select-Object FullName | Where-Object {!($_.psiscontainer)}
作为一个次要问题,psiscontainer部分是什么?我从网上的一个例子中复制了它。
后接编辑:两个很好的答案,希望我能标记它们两个。已授予最初的答案。
$files = Get-ChildItem $directory -Recurse | Select-Object FullName | Where-Object {!($_.psiscontainer)}
FullName
。$files = Get-ChildItem $directory -Recurse | Select-Object FullName | Where-Object {!($_.psiscontainer)} | foreach {$_.FullName}
编辑:对于马克的问题:“foreach是做什么的?它在枚举什么?”我来解释一下。Get-ChildItem $directory -Recurse
Select-Object FullName
Select-Object
在每个 FileSystemInfo
对象到达时,从中获取 FullName
属性(在这种情况下是一个路径),将该属性放入它创建的全新自定义对象中,并将该自定义对象输出到管道中。
Where-Object {!($_.psiscontainer)}
psiscontainer
属性。这个阶段实际上什么都不做。Sung Meister的代码更好。foreach {$_.FullName}
foreach
,其完整名称为ForEach-Object
,在每个对象到达时抓取它,并从中获取FullName
属性,一个字符串。现在,这里有一个微妙的部分:任何未被使用的值,也就是没有被变量捕获或以某种方式被抑制的值,都会被放入输出管道中。作为一个实验,试着用以下内容替换该阶段:foreach {'hello'; $_.FullName; 1; 2; 3}
foreach {'hello'; $_.FullName; $x = 1; 2; 3}
要获取文件名的字符串,您可以使用
$files = Get-ChildItem $directory -Recurse | Where-Object {!($_.psiscontainer)} | Select-Object -ExpandProperty FullName
-ExpandProperty
参数允许您根据指定的属性类型返回对象。
进一步的测试表明,这在V1中不起作用,但该功能已在V2 CTP3中修复。
问题1:
我已经删除了“select-object”部分 - 它是多余的,并将“where”过滤器移动到“foreach”之前,不像dangph的回答 - 尽早过滤,以便在下一个管道线中只处理你需要处理的子集。
$files = Get-ChildItem $directory -Recurse | Where-Object {!$_.PsIsContainer} | foreach {$_.FullName}
这段代码片段基本上读取:
请注意,在 powershell 中,对于 foreach {$_.FullName},脚本块({ ... })中的最后一条语句会被返回,此处为类型为字符串的 $_.FullName。
如果您真的需要获取原始对象,则在去除 "select-object" 后无需进行任何操作。如果您要使用 Select-Object 但想要访问原始对象,请使用 "PsBase",这是一个完全不同的问题(主题) - 参考 "PSBASE、PSEXTENDED、PSADAPTED和PSOBJECT有何区别?" 获取更多关于该主题的信息。
对于问题 #2
并且按照!$_.PsIsContainer 进行过滤意味着您正在排除容器级别的对象 - 在您的情况下,您正在对FileSystem提供程序执行Get-ChildItem(您可以通过Get-PsProvider查看PowerShell提供程序),因此容器是一个DirectoryInfo(文件夹) PsIsContainer 在不同的PowerShell提供程序下具有不同的含义; 例如) 对于Registry提供程序,PsIsContainer的类型为Microsoft.Win32.RegistryKey 尝试这个:>pushd HKLM:\SOFTWARE
>ls | gm
[更新] 对于以下问题: foreach是做什么的?它在枚举什么? 需要澄清的是,"foreach"是"Foreach-Object"的别名。 您可以通过以下方式找到答案,
get-help foreach
- 或 -
get-alias foreach
对于 V1 版本,请在您的配置文件中添加以下过滤器:
filter Get-PropertyValue([string]$name) { $_.$name }
gci . -r | ?{!$_.psiscontainer} | Get-PropertyName fullname
顺便提一下,如果您正在使用PowerShell社区扩展,那么您已经拥有了这个功能。
关于在V2中使用Select-Object -Expand的能力,这是一个巧妙的技巧,但并不明显,而且也不是Select-Object或-Expand的本意。 -Expand是关于像LINQ的SelectMany和Select-Object是关于将多个属性投影到自定义对象上的。
tee-object
将变量分配并发出到输出。例如:ls | select -first 1 -property fullname | %{$_.FullName} | tee -variable firstpath
- Richard Szalay