Tìm kiếm tệp đệ quy bằng PowerShell


238

Tôi đang tìm kiếm một tập tin trong tất cả các thư mục.

Copyforbuild.bat có sẵn ở nhiều nơi và tôi muốn tìm kiếm đệ quy.

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

Làm cách nào tôi có thể làm điều đó trong PowerShell?

Câu trả lời:


393

Sử dụng lệnh ghép ngắn Get-ChildItem với công -Recursetắc:

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

1
Có vẻ như có một vấn đề là nếu nó chạy vào một thư mục mà bạn không có quyền truy cập, toàn bộ tìm kiếm bị hủy bỏ vì quá trình thoát. Có cách nào xung quanh đó không?
deed02392

6
Cố gắng đặt tham số ErrorAction thành Tiếp tục hoặc SilentlyContinue (trong trường hợp giá trị của nó không được đề cập).
Shay Levy

22
Một cách ngắn hơn để làm chính xác điều tương tự: cd V:\MyFoldertiếp theols -r -inc CopyForBuild.bat
Orion Edwards

8
Vì vậy, những gì các nhà bình luận ở trên có nghĩa là ...ls -r -ea silentlycontinue -fo -inc "filename.txt" | % { $_.fullname }
Andrew

Tôi đã điều chỉnh câu trả lời này để thực hiện một phần chuỗi bằng cách thêm ký hiệu astric ( *) vào cuối tên tệp. ****** LINE1: $File = "Microsoft.OData.Core.NetFX35.V7*"LINE2: $Folder = "C:\Program Files"LINE3:Get-ChildItem -Path $Folder -Filter $File -Recurse -ErrorAction SilentlyContinue -Force
SherlockS

37

Tôi sử dụng điều này để tìm tệp và sau đó PowerShell hiển thị toàn bộ đường dẫn của kết quả:

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

Bạn luôn có thể sử dụng ký tự đại diện *trong FolderNamevà / hoặc FileName.fileExtension. Ví dụ:

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

Ví dụ trên sẽ tìm kiếm bất kỳ thư mục trong C:\ổ đĩa bắt đầu bằng từ Folder. Vì vậy, nếu bạn có một thư mục có tên FolderFooFolderBarPowerShell sẽ hiển thị kết quả từ cả hai thư mục đó.

Cũng vậy với tên tập tin và phần mở rộng tập tin. Nếu bạn muốn tìm kiếm một tệp có phần mở rộng nhất định, nhưng không biết tên của tệp, bạn có thể sử dụng:

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

Hoặc ngược lại:

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

4
Tôi thấy câu trả lời này cực kỳ hữu ích vì nó giải quyết một trường hợp sử dụng cụ thể - thực sự muốn sử dụng tệp mà bạn đang tìm kiếm. | để cung cấp cho bạn tên đầy đủ của tệp là một cái gì đó còn thiếu trong các câu trả lời khác.
Nhà phát triển Newteq

1
Tôi phải đồng ý với @ Sanity1123 ở đây, nếu bạn thực sự muốn sử dụng tệp, bạn sẽ cần đường dẫn đầy đủ đến tệp. IMHO đây sẽ là câu trả lời được chấp nhận.
uceumern

31

Khi tìm kiếm các thư mục mà bạn có thể gặp lỗi dựa trên bảo mật (ví dụ C:\Users), hãy sử dụng lệnh sau:

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

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

Cũng sẽ làm việc


Và nếu bạn muốn xuất kết quả ra một tệp, bạn có thể thêm `> path_to_filename.txt` vào cuối lệnh.
Gwen Au

7

Đây là phương pháp mà cuối cùng tôi đã nghĩ ra sau khi vật lộn:

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

Để làm cho đầu ra sạch hơn (chỉ đường dẫn), sử dụng:

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

Để chỉ nhận kết quả đầu tiên, hãy sử dụng:

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

Bây giờ cho những thứ quan trọng:

Để chỉ tìm kiếm các tập tin / thư mục không sử dụng -Filehoặc -Directory(xem bên dưới tại sao). Thay vào đó sử dụng điều này cho các tập tin:

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

và loại bỏ các -eq $falsethư mục cho. Đừng không để lại một ký tự đại diện trailing như bin/*.

Tại sao không sử dụng các thiết bị chuyển mạch tích hợp? Chúng là khủng khiếp và loại bỏ các tính năng ngẫu nhiên. Ví dụ: để sử dụng -Includevới một tệp, bạn phải kết thúc đường dẫn bằng ký tự đại diện. Tuy nhiên, điều này vô hiệu hóa công -Recursetắc mà không cho bạn biết:

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

Bạn sẽ nghĩ rằng nó sẽ cung cấp cho bạn tất *.libcả các thư mục con, nhưng nó sẽ chỉ tìm kiếm cấp cao nhất bin.

Để tìm kiếm các thư mục, bạn có thể sử dụng -Directory, nhưng sau đó bạn phải xóa ký tự đại diện. Vì lý do nào, điều này sẽ không hủy kích hoạt -Recurse. Đó là vì những lý do này mà tôi khuyên bạn không nên sử dụng cờ dựng sẵn.

Bạn có thể rút ngắn lệnh này đáng kể:

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

trở thành

gci './path*/' -s -Include 'name*' | where {$_.PSIsContainer -eq $false}
  • Get-ChildItem được đặt bí danh là gci
  • -Path được mặc định là vị trí 0, vì vậy bạn chỉ cần tạo đường dẫn đối số đầu tiên
  • -Recurse được đặt bí danh là -s
  • -Include không có tốc ký
  • Sử dụng dấu ngoặc đơn cho khoảng trắng trong tên / đường dẫn, để bạn có thể bao quanh toàn bộ lệnh bằng dấu ngoặc kép và sử dụng nó trong Dấu nhắc lệnh. Làm theo cách khác (bao quanh với dấu ngoặc đơn) gây ra lỗi

6

Thử cái này:

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

2
Bạn cũng có thể sử dụng | Where-Object { !$_PSIsContainer }để loại trừ các thư mục
Gargravarr

5

Lọc bằng ký tự đại diện:

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

Lọc bằng biểu thức chính quy:

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

1
Có nên không '\ACopyForBuild\.(bat|cmd)\Z'?
E. Sundin

1

Để thêm vào câu trả lời @ user3303020 và xuất kết quả tìm kiếm thành một tệp, bạn có thể chạy

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

Có thể dễ dàng hơn để tìm kiếm các tập tin chính xác theo cách đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.