Làm cách nào để tìm kiếm một chuỗi trong nhiều tệp và trả về tên của các tệp trong Powershell?


303

Tôi đã bắt đầu học quyền hạn cách đây vài ngày và tôi không thể tìm thấy bất cứ điều gì trên google, đó là những gì tôi cần vì vậy xin vui lòng với câu hỏi của tôi.

Tôi đã được yêu cầu thay thế một số chuỗi văn bản thành nhiều tệp. Tôi không nhất thiết phải biết phần mở rộng của các tệp mục tiêu có thể và tôi cũng không biết vị trí của chúng. Cho đến nay tôi đã quản lý để duyệt đệ quy vào thư mục ( get-ChildItem -recurse) và tìm chuỗi tôi đang tìm kiếm với get-content và select-string:

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy"

Vấn đề là, tôi có thể thấy sự xuất hiện của văn bản mà tôi đang tìm kiếm, nhưng tôi không biết làm thế nào để bảo PS trả lại đường dẫn và tên cho mọi tệp phù hợp.

Làm cách nào tôi có thể nhận được tên và vị trí của các tệp có chứa biểu thức tôi đang tìm kiếm?


2
Có thể chỉnh sửa câu hỏi để chung chung hơn. Câu trả lời cho câu hỏi này không liên quan gì đến JBoss hoặc ứng dụng của bạn mà bạn đang làm việc trên đó dường như ...
Kolob Canyon

5
Tôi chỉ phát hiện bình luận của bạn và chỉnh sửa câu hỏi của tôi ... 2 năm sau! muộn còn hơn không bao giờ .. :)
Bluz

Câu trả lời:


469

Điều này sẽ cung cấp vị trí của các tệp có chứa mẫu của bạn:

Get-ChildItem -Recurse | Select-String "dummy" -List | Select Path

3
Điều gì sẽ xảy ra nếu bạn cũng muốn M CHUYỂN những tệp đó? ... Tôi đang gặp lỗi với điều này khi tôi không thể tham gia | Di chuyển - Mục đến cuối của điều đó.
rud3y

6
Move-Item không có nametham số. Hãy thử thêm| %{Move-Item $_.name <destination>}
jon Z

49
Get-ChildItem -Recurse | Select-String "dummy" -List | Select Pathchỉ trả về kết quả khớp đầu tiên cho mỗi tệp vì vậy có thể hiệu quả hơn một chút và tránh sự cần thiết phải nhóm chúng
ben

5
Điều đáng chú ý là bạn chỉ có thể lọc một loại tệp nhất định, ví dụ như txtcác tệp, nếu bạn sử dụng Get-ChildItem -Recurse -Filter *.txtthay thế
Girardi

@ rud3y Tôi khuyên bạn nên viết nó ra trong một tập lệnh bằng cách sử dụng một foreachvòng lặp nếu bạn đang thực hiện các thao tác lớn như thế. Nó trở nên rất phức tạp khi bạn cố gắng thực hiện tất cả điều đó trên một dòng và rất dễ phạm sai lầm lớn. Tôi nói từ kinh nghiệm
Kolob Canyon

75

Có nhiều câu trả lời chính xác ở đây, nhưng đây là mã ngắn gọn nhất cho một số biến thể khác nhau. Đối với mỗi biến thể, dòng trên cùng hiển thị cú pháp đầy đủ và phía dưới hiển thị cú pháp ngắn gọn.

Mục (2) là một dạng ngắn gọn hơn của các câu trả lời từ Jon Z và manojlds, trong khi mục (1) tương đương với các câu trả lời từ vikas368 và buygrush.

  1. Liệt kê các đối tượng FileInfo cho tất cả các tệp chứa mẫu:

    Get-ChildItem -Recurse filespec | Where-Object { Select-String pattern $_ -Quiet }
    ls -r filespec | ? { sls pattern $_ -q }
    
  2. Liệt kê tên tệp cho tất cả các tệp chứa mẫu:

    Get-ChildItem -Recurse filespec | Select-String pattern | Select-Object -Unique Path
    ls -r filespec | sls pattern | select -u Path
    
  3. Liệt kê các đối tượng FileInfo cho tất cả các tệp không chứa mẫu:

    Get-ChildItem -Recurse filespec | Where-Object { !(Select-String pattern $_ -Quiet) }
    ls -r filespec | ? { !(sls pattern $_ -q) }
    
  4. Liệt kê tên tệp cho tất cả các tệp không chứa mẫu:

    (Get-ChildItem -Recurse filespec | Where-Object { !(Select-String pattern $_ -Quiet) }).FullName
    (ls -r filespec | ? { !(sls pattern $_ -q) }).FullName
    

Ngoài ra, nếu bạn chỉ tìm kiếm Tệp có chứa mẫu ở bất cứ đâu, bạn có thể từ bỏ sau khi tìm phiên bản đầu tiên bằng cách sử dụng -Listtham số củaSelect-String
KyleMit

Tôi ước rằng OP đã hỏi một chút thay đổi của câu hỏi để đây sẽ là AA. # 1 rất hữu ích và rõ ràng là @Michael Sorens mò mẫm PS!
cBlaine

20

Điều này sẽ hiển thị đường dẫn, tên tệp và dòng nội dung mà nó tìm thấy khớp với mẫu.

Get-ChildItem -Path d:\applications\*config -recurse |  Select-String -Pattern "dummy" 

Nếu chỉ có thể thêm một dòng giữa các kết quả :)
cladelpino

15

Nội dung của bạn

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy"

đến fl *

Bạn sẽ thấy rằng đường dẫn đã được trả về như một thuộc tính của các đối tượng.

NẾU bạn chỉ muốn đường dẫn, sử dụng select pathhoặc select -unique pathloại bỏ trùng lặp:

Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy" | select -unique path

1
Cảm ơn cả hai bạn, đây chính xác là những gì tôi đang tìm kiếm. Thật không may, khi có nhiều thư mục con tham gia vào đường dẫn, thì PS sẽ cắt đường dẫn tuyệt đối và thêm ba dấu chấm ở cuối dòng như \ dir1 \ dir2 \ dir3 \ path ... vì vậy tôi không biết tệp nào được trả về . Có cách nào để bảo PS bớt tham lam vào các nhân vật và bận tâm đến việc hiển thị đường dẫn đầy đủ không? :) Cảm ơn rất nhiều !
Bluz

3
Bạn cần thêm công -Filetắc vào Get-ChildItemhoặc bạn kết thúc với một loạt lỗi không bao giờ kết thúc từ việc cố gắng gọi Get-Contentvào thư mục.
RubberDuck

Nếu bạn cần đường dẫn đầy đủ, bạn có thể làm điều này (Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy").FullNameMọi người dường như quên PowerShell là hướng đối tượng; khi nghi ngờ, hãy tìm một bất động sản
Kolob Canyon

10

Đây là cách tôi sẽ làm, bạn không cần nội dung:

ls -r | Select-String dummy | select line,path

hoặc là

ls -r | Select-String dummy | fl *

Để xem các thuộc tính khác nhau là gì ...

Cái này nhanh hơn Đối số thứ hai là -filter:

ls -r . *.bat | select-string netsh

2
+1, Điều này hoạt động hoàn hảo cho trường hợp của tôi, tuy nhiên sử dụng select Pattern, LineNumber, Filenamecho đầu ra ngắn gọn hơn. Dòng trả về MỌI THỨ trên dòng chứa chuỗi mẫu của bạn. Bạn cũng có thể dễ dàng xuất cái này sang csv nếu muốn.
Protonova

9
Get-ChildItem -r | ? {$_.psiscontainer -eq $false} | ? {gc $_.pspath |select-string -pattern "dummy"}

Điều này sẽ cung cấp cho bạn chi tiết đầy đủ của tất cả các tập tin


Hoàn toàn không biết rằng -rđã làm việc. Hình bạn phải luôn luôn làm-Recurse
Kolob Canyon

5

Để giữ chi tiết tệp đầy đủ trong mảng kết quả, bạn có thể sử dụng một sửa đổi nhỏ của câu trả lời được đăng bởi vikas368 (có vẻ như không hoạt động tốt với tự động hoàn thành ISE):

Get-ChildItem -Recurse | Where-Object { $_ | Select-String -Pattern "dummy" }

hoặc nói ngắn gọn:

ls -r | ?{ $_ | Select-String -Pattern "dummy" }

5

Nếu bạn tìm kiếm trong một thư mục, bạn có thể làm điều đó:

select-string -Path "c:\temp\*.*" -Pattern "result"  -List | select Path

4

Điều này sẽ hiển thị một danh sách các đường dẫn đầy đủ đến từng tệp có chứa chuỗi tìm kiếm:

foreach ($file in Get-ChildItem | Select-String -pattern "dummy" | Select-Object -Unique path) {$file.path}

Lưu ý rằng nó không hiển thị tiêu đề phía trên kết quả và không hiển thị các dòng văn bản có chứa chuỗi tìm kiếm. Tất cả những gì nó nói với bạn là nơi bạn có thể tìm thấy các tệp có chứa chuỗi.


2
Bất kỳ ý tưởng làm thế nào để hiển thị số dòng nơi mẫu được tìm thấy, cùng với tên tệp?
Piotr L

4

Tôi đã sửa đổi một trong những câu trả lời ở trên để cung cấp cho tôi thêm một chút thông tin. Điều này cho tôi một truy vấn thứ hai sau này. Nó là một cái gì đó như thế này:

Get-ChildItem `
        -Path "C:\data\path" -Filter "Example*.dat" -recurse | `
    Select-String -pattern "dummy" | `
    Select-Object -Property Path,LineNumber,Line | `
    Export-CSV "C:\ResultFile.csv"

Tôi có thể chỉ định đường dẫn và tệp ký tự đại diện với cấu trúc này và nó lưu tên tệp, số dòng và dòng có liên quan vào một tệp đầu ra.


Mát mẻ! Cảm ơn về giải pháp bổ sung này :) Tuy nhiên, bạn có thể vui lòng liên kết với câu trả lời mà bạn dựa trên giải pháp của mình và đặt tên cho tác giả của câu trả lời đó để cung cấp tín dụng không? Cảm ơn!
Max Vollmer
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.