Рекурсивный поиск файлов с помощью PowerShell

Ищу файл во всех папках.

Copyforbuild.bat доступен во многих местах, и я хотел бы искать рекурсивно.

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

Как это сделать в PowerShell?


person Samselvaprabu    schedule 30.12.2011    source источник


Ответы (9)


Используйте командлет Get-ChildItem с переключателем -Recurse:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force
person Shay Levy    schedule 30.12.2011
comment
Кажется, есть проблема, что если он попадает в каталог, к которому у вас нет разрешения, весь поиск прерывается, потому что процесс завершается. Есть ли способ обойти это? - person deed02392; 20.06.2013
comment
Попробуйте установить для параметра ErrorAction значение Continue или SilentlyContinue (в случае, если его значение не соответствует указанному). - person Shay Levy; 20.06.2013
comment
Более короткий способ сделать то же самое: cd V:\MyFolder, за которым следует ls -r -inc CopyForBuild.bat - person Orion Edwards; 15.08.2014
comment
Итак, что означают комментаторы выше ... ls -r -ea silentlycontinue -fo -inc "filename.txt" | % { $_.fullname } - person Andrew; 04.11.2017
comment
Я адаптировал этот ответ для частичной строки, добавив астрический символ (*) в конец имени файла. ****** СТРОКА1: $File = "Microsoft.OData.Core.NetFX35.V7*" СТРОКА2: $Folder = "C:\Program Files" СТРОКА3: Get-ChildItem -Path $Folder -Filter $File -Recurse -ErrorAction SilentlyContinue -Force - person SherlockSpreadsheets; 29.04.2019
comment
Чтобы добавить к комментариям: разница между filter и inc объясняется здесь. -fo может быть force. % - это псевдоним для foreach-object - person Timo; 08.07.2020

Я использую это для поиска файлов, а затем заставляю PowerShell отображать весь путь к результатам:

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

Вы всегда можете использовать подстановочный знак * в FolderName и / или FileName.fileExtension. Например:

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

В приведенном выше примере выполняется поиск в любой папке на C:\ диске, начинающейся со слова Folder. Итак, если у вас есть папка с именем FolderFoo и FolderBar, PowerShell покажет результаты из обеих этих папок.

То же самое касается имени файла и расширения файла. Если вы хотите найти файл с определенным расширением, но не знаете его имени, вы можете использовать:

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

Или наоборот:

dir -Path C:\FolderName -Filter FileName.* -Recurse | %{$_.FullName}
person BinaryJoe01    schedule 24.01.2017
comment
Я считаю этот ответ чрезвычайно полезным, потому что он касается конкретного варианта использования - на самом деле вы хотите использовать файл, который вы ищете. | чтобы дать вам полное имя файла, чего-то не хватает в других ответах. - person Newteq Developer; 01.08.2017
comment
Я должен согласиться с @ Sanity1123 здесь, если вы действительно хотите использовать файл, вам понадобится полный путь к файлу. ИМХО, это должен быть принятый ответ. - person uceumern; 15.11.2018
comment
Как новичок, у меня проблемы с пониманием того, что происходит после пайпа. Я открыл вопрос по этому поводу. - person Daemon Painter; 10.03.2021
comment
Как говорят другие, это лучший ответ, когда вам нужно сохранить возвращаемое значение. В моем случае мне пришлось найти файл для его удаления, и это упростило задачу. - person xCovelus; 08.04.2021

При поиске папок, в которых вы можете получить ошибку, связанную с безопасностью (например, C:\Users), используйте следующую команду:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force
person Mötz    schedule 28.09.2015

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

Также будет работать

person user3303020    schedule 26.08.2015
comment
А если вы хотите вывести результаты в файл, вы можете добавить «› path_to_filename.txt »в конце команды. - person Gwen Au; 10.10.2019

Вот метод, который я наконец придумал после борьбы:

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 не имеет стенографии
  • Используйте одинарные кавычки для пробелов в именах / путях, чтобы вы могли заключить всю команду в двойные кавычки и использовать ее в командной строке. Если сделать наоборот (заключить в одинарные кавычки), возникнут ошибки.
person Asad-ullah Khan    schedule 29.05.2019

Попробуй это:

Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse | Where-Object { $_.Attributes -ne "Directory"}
person Sevenfold    schedule 07.11.2014
comment
Вы также можете использовать | Where-Object { !$_PSIsContainer } для исключения папок - person Gargravarr; 17.06.2016

Фильтр с использованием подстановочных знаков:

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' }
person MovGP0    schedule 28.07.2016
comment
Разве это не должно быть '\ACopyForBuild\.(bat|cmd)\Z'? - person E. Sundin; 18.03.2019

Чтобы добавить к @ user3303020 ответ и вывести результаты поиска в файл, вы можете запустить

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

Так будет проще найти нужный файл.

person Gwen Au    schedule 10.10.2019

для поиска всех файлов с расширением py, начиная с / введите: dir -r * .py или dir * .py -r

person Hector Abreu    schedule 22.07.2021