Pesquisa de arquivos recursivos usando o PowerShell

238

Estou procurando um arquivo em todas as pastas.

Copyforbuild.bat está disponível em muitos lugares e eu gostaria de pesquisar recursivamente.

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

Como posso fazer isso no PowerShell?

Samselvaprabu
fonte

Respostas:

393

Use o cmdlet Get-ChildItem com a -Recurseopção:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force
Shay Levy
fonte
1
Parece ter um problema que, se for executado em um diretório que você não tem permissão para acessar, toda a pesquisa será abortada porque o processo termina. Existe uma maneira de contornar isso?
deed02392
6
Tente definir o parâmetro ErrorAction como Continue ou SilentlyContinue (caso seu valor não seja o mencionado).
Shay Levy
22
Uma maneira mais curta de fazer exatamente a mesma coisa: cd V:\MyFolderseguido porls -r -inc CopyForBuild.bat
Orion Edwards
8
Então, o que os comentadores acima média é ...ls -r -ea silentlycontinue -fo -inc "filename.txt" | % { $_.fullname }
Andrew
Eu adaptei esta resposta para fazer uma string parcial adicionando o símbolo astric ( *) ao final do nome do arquivo. ****** LINE1: $File = "Microsoft.OData.Core.NetFX35.V7*"LINE2: $Folder = "C:\Program Files"LINE3:Get-ChildItem -Path $Folder -Filter $File -Recurse -ErrorAction SilentlyContinue -Force
SherlockSpreadsheets
37

Eu uso isso para encontrar arquivos e, em seguida, o PowerShell exibe o caminho inteiro dos resultados:

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

Você sempre pode usar o curinga *no FolderNamee / ou FileName.fileExtension. Por exemplo:

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

O exemplo acima irá procurar qualquer pasta no C:\início de carro com a palavra Folder. Portanto, se você tiver uma pasta chamada FolderFooe o FolderBarPowerShell mostrará resultados de ambas as pastas.

O mesmo vale para o nome e a extensão do arquivo. Se você deseja procurar um arquivo com uma certa extensão, mas não sabe o nome do arquivo, pode usar:

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

Ou vice-versa:

dir -Path C:\FolderName -Filter FileName.* -Recurse | %{$_.FullName}
BinaryJoe01
fonte
4
Acho essa resposta extremamente útil porque aborda um caso de uso específico - na verdade, quero usar o arquivo que você está procurando. O | dar a você o nome completo do arquivo está faltando nas outras respostas.
Newteq Developer
1
Eu tenho que concordar com @ Sanity1123 aqui, se você realmente quiser usar o arquivo, precisará do caminho completo para o arquivo. IMHO esta deve ser a resposta aceita.
uceumern
31

Ao pesquisar pastas nas quais você pode obter um erro com base na segurança (por exemplo C:\Users), use o seguinte comando:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force
Mötz
fonte
12
Get-ChildItem V:\MyFolder -name -recurse *.CopyForbuild.bat

Também vai funcionar

user3303020
fonte
E se você deseja gerar resultados para um arquivo, você pode adicionar `> path_to_filename.txt` no final do comando.
Gwen Au
7

Aqui está o método que eu finalmente criei depois de lutar:

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

Para tornar a saída mais limpa (somente caminho), use:

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

Para obter apenas o primeiro resultado, use:

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

Agora, o importante:

Para pesquisar apenas arquivos / diretórios, não use -Fileou -Directory(veja abaixo o porquê). Em vez disso, use isso para arquivos:

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

e remova os -eq $falsediretórios for. Você não deixar um curinga arrastando como bin/*.

Por que não usar os switches integrados? Eles são terríveis e removem recursos aleatoriamente. Por exemplo, para usar -Includecom um arquivo, você deve finalizar o caminho com um curinga. No entanto, isso desativa a -Recurseopção sem informar:

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

Você pensaria que isso daria todos os *.libs em todos os subdiretórios, mas somente o nível superior será pesquisado bin.

Para procurar diretórios, você pode usar -Directory, mas remover o curinga à direita. Por qualquer motivo, isso não será desativado -Recurse. É por esses motivos que eu recomendo não usar os sinalizadores internos.

Você pode reduzir esse comando consideravelmente:

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

torna-se

gci './path*/' -s -Include 'name*' | where {$_.PSIsContainer -eq $false}
  • Get-ChildItem é um alias para gci
  • -Path é o padrão para a posição 0, então você pode apenas fazer o primeiro caminho do argumento
  • -Recurse é um alias para -s
  • -Include não tem taquigrafia
  • Use aspas simples para espaços em nomes / caminhos, para que você possa colocar o comando inteiro entre aspas duplas e usá-lo no prompt de comando. Fazer o contrário (cercar com aspas simples) causa erros
hLk
fonte
6

Tente o seguinte:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse | Where-Object { $_.Attributes -ne "Directory"}
Sete vezes
fonte
2
Você também pode usar | Where-Object { !$_PSIsContainer }para excluir pastas
Gargravarr
5

Filtrar usando curingas:

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

Filtrando usando uma expressão regular:

Get-ChildItem -Path "V:\Myfolder" -Recurse
| Where-Object { $_.Name -match '\ACopyForBuild\.[(bat)|(cmd)]\Z' }
MovGP0
fonte
1
Não deveria ser '\ACopyForBuild\.(bat|cmd)\Z'?
E. Sundin
1

Para adicionar à resposta @ user3303020 e gerar os resultados da pesquisa em um arquivo, você pode executar

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

Pode ser mais fácil procurar o arquivo correto dessa maneira.

Gwen Au
fonte