tra-loi-cau-hoi-phat-trien-web.com

Làm cách nào để xóa đệ quy toàn bộ thư mục với PowerShell 2.0?

Cách đơn giản nhất để xóa mạnh một thư mục và tất cả các thư mục con của nó trong PowerShell là gì? Tôi đang sử dụng PowerShell V2 trong Windows 7.

Tôi đã học được từ một số nguồn rằng lệnh rõ ràng nhất, Remove-Item $targetDir -Recurse -Force, không hoạt động chính xác. Điều này bao gồm một tuyên bố trong trợ giúp trực tuyến PowerShell V2 (được tìm thấy bằng cách sử dụng Get-Help Remove-Item -Examples) nói rằng:

... Vì tham số Recurse trong lệnh ghép ngắn này bị lỗi, nên lệnh sử dụng lệnh ghép ngắn Get-Childitem để lấy các tệp mong muốn và nó sử dụng toán tử đường ống để chuyển chúng đến lệnh ghép ngắn Loại bỏ ...

Tôi đã thấy các ví dụ khác nhau sử dụng Get-ChildItem và chuyển nó thành Remove-Item, nhưng các ví dụ thường xóa một số tập tin dựa trên bộ lọc, không phải toàn bộ thư mục .

Tôi đang tìm cách sạch nhất để thổi bay toàn bộ thư mục, tệp và thư mục con mà không tạo ra bất kỳ thông báo cảnh báo người dùng nào sử dụng ít mã nhất. Một lớp lót sẽ là tốt đẹp nếu nó dễ hiểu.

240
Matt Spradley
Remove-Item -Recurse -Force some_dir

thực sự làm việc như quảng cáo ở đây.

rm -r -fo some_dir

là bí danh tốc ký cũng hoạt động.

Theo như tôi hiểu, tham số -Recurse không hoạt động chính xác khi bạn cố gắng xóa một tập hợp các tệp được lọc theo cách đệ quy. Đối với việc giết một thư mục duy nhất và mọi thứ bên dưới dường như hoạt động tốt.

412
Joey

Tôi đã sử dụng:

rm -r folderToDelete

Điều này đối với tôi như một cơ duyên (tôi đã đánh cắp nó từ Ubuntu).

36
Tuan Jinn

Khi xóa các tệp đệ quy bằng cách sử dụng Remove-Item "folder" -Recurse đơn giản, đôi khi tôi gặp lỗi không liên tục: [folder] cannot be removed because it is not empty.

Câu trả lời này cố gắng ngăn chặn lỗi đó bằng cách xóa từng tệp.

function Get-Tree($Path,$Include='*') { 
    @(Get-Item $Path -Include $Include -Force) + 
        (Get-ChildItem $Path -Recurse -Include $Include -Force) | 
        sort pspath -Descending -unique
} 

function Remove-Tree($Path,$Include='*') { 
    Get-Tree $Path $Include | Remove-Item -force -recurse
} 

Remove-Tree some_dir

Một chi tiết quan trọng là sắp xếp tất cả các mục với pspath -Descending để các lá bị xóa trước gốc. Việc sắp xếp được thực hiện trên tham số pspath vì điều đó có nhiều cơ hội làm việc cho các nhà cung cấp khác ngoài hệ thống tệp. Tham số -Include chỉ là sự tiện lợi nếu bạn muốn lọc các mục cần xóa.

Nó được chia thành hai chức năng vì tôi thấy hữu ích khi xem những gì tôi sắp xóa bằng cách chạy

Get-Tree some_dir | select fullname
20
John Rees

Hãy thử ví dụ này. Nếu thư mục không tồn tại, không có lỗi nào được nêu ra. Bạn có thể cần PowerShell v3.0.

remove-item -path "c:\Test Temp\Test Folder" -Force -Recurse -ErrorAction SilentlyContinue
10
steve
rm -r ./folder -Force    

...đã làm cho tôi

9
stevethecollier

Sử dụng lệnh DOS trường học cũ:

rd /s <dir>
8
Anonymous

Để tránh các lỗi "Thư mục không trống" của câu trả lời được chấp nhận, chỉ cần sử dụng lệnh DOS cũ như đề xuất trước đây. Cú pháp PS đầy đủ đã sẵn sàng để sao chép là:

& cmd.exe /c rd /S /Q $folderToDelete
6
Dejan

Vì một số lý do, câu trả lời của John Rees đôi khi không hoạt động trong trường hợp của tôi. Nhưng nó đã dẫn tôi theo hướng sau. Đầu tiên tôi cố gắng xóa thư mục theo cách đệ quy với tùy chọn buggy -recurse. Sau đó tôi đi xuống mọi thư mục con còn lại và xóa tất cả các tệp.

function Remove-Tree($Path)
{ 
    Remove-Item $Path -force -Recurse -ErrorAction silentlycontinue

    if (Test-Path "$Path\" -ErrorAction silentlycontinue)
    {
        $folders = Get-ChildItem -Path $Path –Directory -Force
        ForEach ($folder in $folders)
        {
            Remove-Tree $folder.FullName
        }

        $files = Get-ChildItem -Path $Path -File -Force

        ForEach ($file in $files)
        {
            Remove-Item $file.FullName -force
        }

        if (Test-Path "$Path\" -ErrorAction silentlycontinue)
        {
            Remove-Item $Path -force
        }
    }
}
5
jdoose

Tôi đã thực hiện một cách tiếp cận khác lấy cảm hứng từ @ john-rees ở trên - đặc biệt là khi cách tiếp cận của anh ấy bắt đầu thất bại đối với tôi tại một số điểm. Về cơ bản lặp lại các cây con và sắp xếp các tệp theo độ dài đường dẫn của chúng - xóa từ dài nhất đến ngắn nhất

Get-ChildItem $tfsLocalPath -Recurse |  #Find all children
    Select-Object FullName,@{Name='PathLength';Expression={($_.FullName.Length)}} |  #Calculate the length of their path
    Sort-Object PathLength -Descending | #sort by path length descending
    %{ Get-Item -LiteralPath $_.FullName } | 
    Remove-Item -Force

Về phép thuật -LiteralPath, đây là một gotchya khác có thể đánh bạn: https://superuser.com/q/212808

2
Peter McEvoy

Xóa toàn bộ cây thư mục đôi khi hoạt động và đôi khi không thành công với lỗi "Thư mục không trống". Sau đó, cố gắng kiểm tra xem thư mục có còn tồn tại có thể dẫn đến lỗi "Truy cập bị từ chối" hoặc "Truy cập trái phép" hay không. Tôi không biết tại sao điều này xảy ra, mặc dù một số thông tin chi tiết có thể thu được từ bài đăng StackOverflow này .

Tôi đã có thể khắc phục các vấn đề này bằng cách chỉ định thứ tự các mục trong thư mục bị xóa và bằng cách thêm độ trễ. Sau đây chạy tốt cho tôi:

# First remove any files in the folder tree
Get-ChildItem -LiteralPath $FolderToDelete -Recurse -Force | Where-Object { -not ($_.psiscontainer) } | Remove-Item –Force

# Then remove any sub-folders (deepest ones first).    The -Recurse switch may be needed despite the deepest items being deleted first.
ForEach ($Subfolder in Get-ChildItem -LiteralPath $FolderToDelete -Recurse -Force | Select-Object FullName, @{Name="Depth";Expression={($_.FullName -split "\\").Count}} | Sort-Object -Property @{Expression="Depth";Descending=$true}) { Remove-Item -LiteralPath $Subfolder.FullName -Recurse -Force }

# Then remove the folder itself.  The -Recurse switch is sometimes needed despite the previous statements.
Remove-Item -LiteralPath $FolderToDelete -Recurse -Force

# Finally, give Windows some time to finish deleting the folder (try not to hurl)
Start-Sleep -Seconds 4

Một bài viết của Microsoft TechNet Sử dụng các thuộc tính được tính toán trong PowerShell rất hữu ích cho tôi trong việc lấy danh sách các thư mục con được sắp xếp theo độ sâu.

Các vấn đề độ tin cậy tương tự với RD/S/Q có thể được giải quyết bằng cách chạy RD/S/Q hai lần - lý tưởng là tạm dừng ở giữa (tức là sử dụng ping như hiển thị bên dưới).

RD /S /Q "C:\Some\Folder\to\Delete" > nul
if exist "C:\Some\Folder\to\Delete"  ping -4 -n 4 127.0.0.1 > nul
if exist "C:\Some\Folder\to\Delete"  RD /S /Q "C:\Some\Folder\to\Delete" > nul
1
MikeOnline

Thực sự đơn giản:

remove-item -path <type in file or directory name>, press Enter
1
DusanV

Để xóa nội dung đầy đủ bao gồm cả cấu trúc thư mục sử dụng

get-childitem $dest -recurse | foreach ($_) {remove-item $_.fullname -recurse}

-recurse được thêm vào remove-item đảm bảo lời nhắc tương tác bị tắt.

1
steve simon
del <dir> -Recurse -Force # I prefer this, short & sweet

OR

remove-item <dir> -Recurse -Force

Nếu bạn có một thư mục lớn thì những gì tôi thường làm là

while (dir | where name -match <dir>) {write-Host deleting; sleep -s 3}

Chạy cái này trên một thiết bị đầu cuối powershell và nó sẽ dừng lại khi nó được thực hiện.

1
Gajendra D Ambi

Một mẹo hữu ích khác :

Nếu bạn tìm thấy rất nhiều tệp có quy ước tên giống hoặc tương tự (như tệp mac có tên tiền tố dấu chấm ... kéo tệp nổi tiếng đó), bạn có thể dễ dàng xóa chúng bằng một dòng duy nhất từ ​​quyền hạn như sau:

ls -r .* | rm

Dòng này sẽ xóa tất cả các tệp có dấu chấm ở đầu tên trong thư mục hiện tại và tất cả các tệp có cùng hoàn cảnh bên trong các thư mục khác trong thư mục này. Hãy nhận biết về nó khi sử dụng nó. : D