从Select-String输出中获取“父文件夹+文件名”

3

我正在编写一个简单的脚本,用于递归列出文件夹 "fullscreen" 中包含单词 'plugin' 的所有文件。因为路径太长且不必要,所以我决定只获取文件名。 问题在于所有文件都称为“index.xml”,因此如果能得到“包含文件夹+文件名”就非常有帮助了。因此,输出将类似于这样:

on\index.xml
off\index.xml

改为:

C:\this\is\a\very\long\path\fullscreen\on\index.xml
C:\this\is\a\very\long\path\fullscreen\off\index.xml

这是我所拥有的:

dir .\fullscreen | sls plugin | foreach { write-host $($_).path }

我遇到了这个错误:

由于为空值,无法将参数“Path”绑定到参数。

2个回答

8
你离成功不远了::-)
dir .\fullscreen | sls plugin | foreach { write-host $_.path }

这个也可以工作:
dir .\fullscreen | sls plugin | foreach { write-host "$($_.path)" }

顺便说一下,我通常会避免使用Write-Host,除非你只是想为坐在控制台旁的某个人显示信息。如果以后想捕获此输出到变量中,它不会像现在这样工作:

$files = dir .\fullscreen | sls plugin | foreach { write-host $_.path } # doesn't work

大多数情况下,您可以通过使用标准输出流来实现相同的输出并将其捕获到变量中,例如:
dir .\fullscreen | sls plugin | foreach { $_.path }

如果您正在使用 PowerShell v3,您可以简化为以下方式:

dir .\fullscreen | sls plugin | % Path

更新: 要仅获取包含文件夹名称,请执行以下操作:

dir .\fullscreen | sls plugin | % {"$(split-path (split-path $_ -parent) -leaf)\$($_.Filename)"}

谢谢你的帮助,但我认为你没有理解我想要实现的目标。我已经编辑了我的问题,提供了更多关于我所寻找的输出类型的细节。祝好。 - RafaelGP

1
< p > FileInfo 类的 Directory 属性告诉您父目录,您只需获取其基础并与文件名连接即可。请注意额外的 foreach 将项目转换回 FileInfo 对象:

dir .\fullscreen | sls plugin | foreach{ get-item $_.Path } | foreach { write-output (join-path $_.Directory.BaseName $_.Name)}

如果您想避免额外的管道,请使用以下代码:

dir .\fullscreen | sls plugin | foreach{ $file = get-item $_.Path; write-output (join-path $file.Directory.BaseName $file.Name)}

Select-String 输出的是 MatchInfo 对象,而不是 FileInfo 对象,因此它上面没有 Directory 属性可用。 - Keith Hill
@Keith谢谢,我忘了那个。我编辑了我的答案,提供了一个稍微不同的方法。 - zdan
让我们再试一次...在PowerShell V4中,您将能够通过“-PipelineVariable”参数(别名pv)使用FileInfo,例如dir .\fullscreen -pv fi | sls plugin | foreach { write-output (join-path $fi.Directory.BaseName $_.Filename)} - Keith Hill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接