我正在所有的文件夹中查找一个文件。

Copyforbuild.bat在很多地方都有,我想递归搜索。

$File = "V:\Myfolder\**\*.CopyForbuild.bat"

如何在PowerShell中做到这一点?


当前回答

使用通配符过滤:

Get-ChildItem -Filter CopyForBuild* -Include *.bat,*.cmd -Exclude *.old.cmd,*.old.bat -Recurse

使用正则表达式进行过滤:

Get-ChildItem -Path "V:\Myfolder" -Recurse
| Where-Object { $_.Name -match '\ACopyForBuild\.[(bat)|(cmd)]\Z' }

其他回答

使用带有-递归开关的Get-ChildItem cmdlet:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force

试试这个:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse | Where-Object { $_.Attributes -ne "Directory"}

这是我在苦苦挣扎后最终想出的方法:

Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*

为了使输出更干净(唯一路径),使用:

(Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*).fullname

要只得到第一个结果,使用:

(Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*).fullname | Select -First 1

现在说重要的事情:

如果只搜索文件/目录,不要使用-File或-Directory(原因见下文)。相反,在文件中使用这个:

Get-ChildItem -Recurse -Path ./path*/ -Include name* | where {$_.PSIsContainer -eq $false}

并删除目录的-eq $false。不要在后面留下像bin/*这样的通配符。

为什么不使用内置开关呢?它们很糟糕,随意删除功能。例如,为了在文件中使用-Include,必须以通配符结束路径。然而,这将禁用递归开关而不告诉你:

Get-ChildItem -File -Recurse -Path ./bin/* -Include *.lib

你以为那样你就能得到*。lib在所有子目录中,但它只会搜索bin的顶层。

为了搜索目录,可以使用-Directory,但随后必须删除后面的通配符。不管出于什么原因,这不会使-Recurse失效。正是由于这些原因,我建议不要使用内置标志。

你可以大大缩短这个命令:

Get-ChildItem -Recurse -Path ./path*/ -Include name* | where {$_.PSIsContainer -eq $false}

就变成了

gci './path*/' -s -Include 'name*' | where {$_.PSIsContainer -eq $false}

Get-ChildItem别名为gci -Path默认位置为0,所以你可以将第一个参数设为path -Recurse别名为-s -Include没有简写 名称/路径中的空格使用单引号,这样您就可以用双引号括起整个命令并在命令提示符中使用它。反过来做(用单引号括起来)会导致错误

Windows系统: 搜索'c:\temp'目录下的所有。py文件,输入:dir -r *.py或dir *.py -r

*Nix (Linux / MacOs系统: 在终端类型:find /temp -name *.py

这对我来说很好。

Get-ChildItem V:\MyFolder -name -recurse *.CopyForbuild.bat

也可以