使用PowerShell进行递归文件搜索

327

我正在搜索所有文件夹中的一个文件。

Copyforbuild.bat 在许多地方都可用,我想要递归搜索。

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

如何在PowerShell中实现这个?

10个回答

508

使用带有 -Recurse 开关的 Get-ChildItem 命令。

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

2
似乎存在一个问题,如果它遇到一个你没有权限访问的目录,整个搜索就会被中止,因为进程退出了。有什么解决办法吗? - deed02392
6
尝试将ErrorAction参数设置为Continue或SilentlyContinue(如果其值不是如上所述)。 - Shay Levy
37
完全相同操作的更短方式: 先执行 cd V:\MyFolder,然后执行 ls -r -inc CopyForBuild.bat - Orion Edwards
15
以上评论者的意思是... ls -r -ea silentlycontinue -fo -inc "filename.txt" | % { $_.fullname }。该命令用于在当前目录及其子目录中搜索名为 "filename.txt" 的文件,并将结果以完整路径的形式输出。其中,-r 表示递归搜索,-ea silentlycontinue 表示忽略错误并继续执行,-fo 表示仅输出文件而非文件夹,-inc 表示仅匹配包含指定字符串的文件名。管道符 | 将搜索结果传递给后面的命令进行处理,% { $_.fullname } 则表示对每个搜索结果输出其完整路径。 - Andrew
2
补充评论:filterinc 之间的差异在这里解释。 -fo 可能是“强制”(force)的缩写。 %foreach-object 的别名。 - Timo
显示剩余5条评论

76

我使用这个工具来查找文件,并让PowerShell显示结果的完整路径:

dir -Path C:\FolderName -Filter FileName.fileExtension -Recurse | %{$_.FullName}

您可以在FolderName和/或FileName.fileExtension中始终使用通配符*。例如:

dir -Path C:\Folder* -Filter File*.file* -Recurse | %{$_.FullName}

以上示例将搜索以单词“Folder”开头的C:\驱动器中的任何文件夹。因此,如果您有一个名为FolderFooFolderBar的文件夹,则PowerShell将显示来自这些文件夹的结果。

文件名和文件扩展名也是如此。如果您想搜索具有特定扩展名的文件,但不知道文件名,可以使用:

dir -Path C:\FolderName -Filter *.fileExtension -Recurse | %{$_.FullName}

或者反过来:

dir -Path C:\FolderName -Filter FileName.* -Recurse | %{$_.FullName}

5
我觉得这个答案非常有用,因为它解决了一个特定的用例——实际想要使用你正在寻找的文件。使用竖杠符号来给出文件的完整名称是其他答案中缺少的内容。 - Newteq Developer
2
我必须在这里同意@Sanity1123的观点,如果你真的想使用这个文件,你需要文件的完整路径。在我看来,这应该是被接受的答案。 - uceumern
作为一个初学者,我很难理解管道符号后面在发生什么。我已经在Stack Overflow上开了一个问题来求解答案。 - Daemon Painter
1
就像其他人所说,当您需要存储返回值时,这是最好的答案。在我的情况下,我必须找到一个文件并将其删除,这使得操作变得更加容易。 - xCovelus

34

当搜索可能基于安全性(例如C:\ Users)导致错误的文件夹时,请使用以下命令:

在搜索栏中输入以下内容:

dir /a-r-h-s /b "C:\Users"
Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force

21

在苦苦挣扎之后,我最终想出了这个方法:

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,必须以通配符结尾。但是,这会禁用-Recurse开关,而且没有告诉你:

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,因此您可以将第一个参数作为路径
  • -Recurse 的别名为 -s
  • -Include 没有简称
  • 在名称/路径中使用单引号代替空格,这样您就可以用双引号将整个命令括起来并在命令提示符中使用它。使用相反的方式(用单引号括起来)会导致错误

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

同样也可以工作


如果你想将结果输出到文件中,你可以在命令的末尾添加 > path_to_filename.txt - Gwen Au
对于当前目录,Get-ChildItem . -name -recurse *.bat 对我很有用。 - cmhughes

8
使用通配符进行过滤:
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' }

1
难道不应该是 '\ACopyForBuild\.(bat|cmd)\Z' 吗? - E. Sundin

7

试试这个:

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

2
你也可以使用 | Where-Object { !$_PSIsContainer } 来排除文件夹。 - Gargravarr

2
要补充@user3303020的答案并将搜索结果输出到文件中,您可以运行
Get-ChildItem V:\MyFolder -name -recurse *.CopyForbuild.bat > path_to_results_filename.txt

这样搜索正确的文件可能更容易。

0

在 Windows 系统上: 搜索“c:\temp”目录及其子目录中的所有 .py 文件,输入:dir -r *.py 或 dir *.py -r。

在 *Nix(Linux / MacOs)系统上: 在终端中输入:find /temp -name *.py。

这对我很有用。


不确定为什么这个系统阻止我添加评论。 - Hector Abreu

0

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