Câu hỏi Làm cách nào để xóa một tệp trong một thư mục phù hợp với cụm từ thông dụng bằng PowerShell?


Tôi biết một đặc điểm chung của tên tệp của một số tệp không mong muốn trên máy tính Windows của tôi. Làm thế nào tôi có thể loại bỏ tất cả các tập tin này từ một hệ thống phân cấp thư mục hoặc thư mục nhất định với một biểu hiện thông thường Lệnh PowerShell?


17
2018-05-20 18:38


gốc




Các câu trả lời:


Bạn có thể đường ống lệnh Get-ChildItem thông qua bộ lọc Object-Object chấp nhận mẫu RegEx và sau đó đưa nó vào Remove-Item. Tôi nghĩ rằng sẽ giúp bạn có được kết quả nhanh hơn và tốt hơn so với sử dụng Select-String. Với một lệnh như:

Get-ChildItem $Path | Where{$_.Name -Match "<RegEx Pattern>"} | Remove-Item

Thuộc tính Tên sẽ chỉ khớp với tên của tệp hoặc thư mục, cùng với phần mở rộng của tệp. Nó sẽ không phù hợp với những thứ khác dọc theo con đường. Điều này sẽ vượt qua một đối tượng FileInfo xuống đường ống mà Remove-Item lấy làm đầu vào đường ống và sẽ loại bỏ các tệp đang được đề cập đến.

Nếu bạn muốn bao gồm các thư mục con của đường dẫn của bạn, bạn sẽ thêm công tắc -Recurse vào lệnh Get-ChildItem của bạn và nó sẽ trông giống như sau:

Get-ChildItem $Path -Recurse | Where{$_.Name -Match "<RegEx Pattern>"} | Remove-Item

Nếu bạn chỉ muốn xóa các tệp, bạn có thể chỉ định trong câu lệnh Where bằng cách xem thuộc tính PSIsContainer của đối tượng FileInfo và đảo ngược nó bằng cách thêm tiền tố cho đối tượng với dấu chấm than như sau:

Get-ChildItem $Path -Recurse | Where{$_.Name -Match "<RegEx Pattern>" -and !$_.PSIsContainer} | Remove-Item

24
2018-05-20 19:28



Chú thích: Get-ChildItem không truy xuất các tệp bị ẩn theo mặc định. Hành vi này có thể được thay đổi với -Force hoặc là -Attributes: technet.microsoft.com/en-us/library/hh847897.aspx - dfernan


Bạn có thể sử dụng lệnh,

ls -name | select-string -pattern ".*\(\d+\).*" | %{rm $_}

Trường hợp nội dung của dấu ngoặc kép là cụm từ thông dụng của bạn. Regex trong ví dụ này tìm kiếm các tệp có (#) trong tên tệp, trong đó # là bất kỳ số nguyên không âm nào. Điều này rất hữu ích cho việc xóa các bản sao trong một thư mục mà cùng một tập hợp các tệp đã bị bán phá giá nhiều lần, chẳng hạn như bởi một trình quản lý nhạc.

Nếu bạn thêm a -r sau tên

ls -name -r | select-string -pattern ".*\(\d+\).*" | %{rm $_}

nó sẽ recurse thông qua các thư mục con và xóa các tập tin phù hợp trong tất cả các thư mục con.

Cấu trúc của lệnh như sau:

  • ls là một bí danh cho lệnh powershell get-childitem. Nó liệt kê tất cả các phần tử trong thư mục hiện hành. Đối số -name xác định rằng chỉ các tên được tạo ra; Tôi không muốn các thông tin khác như kích thước tệp.
  • select-string là chủ yếu tương đương với UNIX grep, nơi nó khớp với một mẫu (regex) với một chuỗi các chuỗi được phân cách bằng dòng. Tham số -pattern đặt lệnh ghép ngắn lên để lấy một regex.
  • % {rm $} là một vòng lặp foreach. Nó nói rằng, "cho mỗi dòng đường ống vào tôi (từ chọn chuỗi trong trường hợp này)", thực hiện hành động sau, trong đó $ là dòng đã cho. Trong trường hợp này, chúng ta đang rm-ing item, trong đó rm là một bí danh cho Remove-Item.

4
2018-05-20 18:38



Select-String được thiết kế để tìm kiếm thông tin trong các tập tin. Nó trả về các đối tượng MatchInfo chứa thông tin như tên tệp và số dòng nơi kết quả trùng khớp được tìm thấy. Trong bối cảnh này, tất cả những thông tin đó là vô ích và chi phí mà nó thêm vào là lãng phí. Thao tác -match đơn giản sẽ nhanh hơn, đơn giản hơn và hiệu quả hơn. - mjolinor
Tôi sẽ thêm rằng -name tham số đầu ra chỉ chuỗi, vì vậy bạn mất tất cả các siêu dữ liệu tệp khác (Length, LastWriteTime, v.v.) Tôi khuyên bạn nên kết hợp trên Name thay vào đó (sử dụng -match như mjolinor gợi ý). - Bill_Stewart
@Bill_Stewart - Tôi khuyên bạn nên sử dụng Tên đầy đủ, đặc biệt nếu bạn thực hiện việc tái chế. - mjolinor
@mjolinor - Có, nếu phần đường dẫn của tên là quan trọng, tất nhiên tôi đồng ý. - Bill_Stewart


Tôi sẽ sử dụng điều này:

(Get-ChildItem -Path $Path | Select -ExpandProperty Fullname) -match <regex> | Remove-Item
(Get-ChildItem -Path $Path -Recurse | Select -ExpandProperty Fullname) -match <regex> | Remove-Item

hoặc nếu bạn đã có V3 hoặc cao hơn, do đó bạn có tự động liệt kê thành viên:

 (Get-ChildItem -Path $Path).Fullname -match <regex> | Remove-Item
 (Get-ChildItem -Path $Path -Recurse).Fullname -match <regex> | Remove-Item

Tên sẽ chỉ hoạt động nếu thư mục làm việc hiện tại của bạn là thư mục bạn đang xóa tệp và tất cả các tệp nằm trong thư mục đó (một thư viện có thể tìm thấy nhiều tệp có cùng tên, nhưng các đường dẫn khác nhau).


2
2018-05-20 19:43



Việc truyền toàn bộ đối tượng FileInfo (thay vì một chuỗi) vào lệnh Remove-Item sẽ loại bỏ nó ngay cả khi nó không nằm trong đường dẫn hiện tại của bạn. So khớp với Tên tránh các kết quả trùng khớp giả từ các mẫu regex đơn giản vô tình khớp với thư mục mẹ. - TheMadTechnician
Đúng vậy, nhưng điều đó có vẻ giống như một cái nạng để bảo vệ bản thân khỏi các chính trị của riêng bạn. - mjolinor
Nếu bạn đang tìm kiếm để phù hợp với một mô hình trong một tên tập tin / thư mục, sau đó có thực sự không nên có bất kỳ cần phải có đường dẫn đầy đủ. OP cho biết regex khớp với một mẫu trong tên tệp, tham chiếu toàn bộ đường dẫn có nghĩa là bạn phải dành nhiều thời gian hơn cho mẫu regex của mình và làm cho nó chính xác hơn. Tôi sẽ không gọi tham chiếu Tên một cái nạng quá nhiều như chỉ làm việc với những gì cần thiết cho nhiệm vụ mong muốn. - TheMadTechnician