use - windows powershell remove file




Como excluir recursivamente um diretório inteiro com o PowerShell 2.0? (11)

Qual é a maneira mais simples de excluir com força um diretório e todos os seus subdiretórios no PowerShell? Estou usando o PowerShell V2 no Windows 7.

Eu aprendi com várias fontes que o comando mais óbvio, Remove-Item $targetDir -Recurse -Force , não funciona corretamente. Isso inclui uma declaração na ajuda on-line do PowerShell V2 (encontrada usando Get-Help Remove-Item -Examples ) que declara:

... Como o parâmetro Recurse neste cmdlet está com defeito, o comando usa o cmdlet Get-Childitem para obter os arquivos desejados e usa o operador de pipeline para passá-los ao cmdlet Remove-Item ...

Eu vi vários exemplos que usam Get-ChildItem e canalizá-lo para Remove-Item , mas os exemplos geralmente removem alguns conjuntos de arquivos com base em um filtro, não no diretório inteiro.

Eu estou procurando a maneira mais limpa para soprar um diretório inteiro, arquivos e diretórios filho, sem gerar mensagens de aviso de usuário usando a menor quantidade de código. Um one-liner seria bom se fosse fácil de entender.


A exclusão de uma árvore de pastas inteira às vezes funciona e às vezes falha com erros "Diretório não vazio". Subseqüentemente, tentar verificar se a pasta ainda existe pode resultar em erros de "Acesso negado" ou "Acesso não autorizado". Eu não sei porque isso acontece, apesar de alguns insights podem ser obtidos a partir deste lançamento .

Consegui contornar esses problemas especificando a ordem em que os itens da pasta são excluídos e adicionando atrasos. O seguinte corre bem para mim:

# 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

Um artigo do Microsoft TechNet Usando Propriedades Calculadas no PowerShell foi útil para obter uma lista de subpastas classificadas por profundidade.

Problemas de confiabilidade similares com RD / S / Q podem ser resolvidos executando RD / S / Q duas vezes - idealmente com uma pausa no meio (ou seja, usando o ping como mostrado abaixo).

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

Ao excluir arquivos de forma recursiva usando uma simples Remove-Item "folder" -Recurse , às vezes vejo um erro intermitente: [folder] cannot be removed because it is not empty.

Essa resposta tenta evitar esse erro excluindo os arquivos individualmente.

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

Um detalhe importante é a classificação de todos os itens com pspath -Descending modo que as folhas sejam deletadas antes das raízes. A classificação é feita no parâmetro pspath uma vez que tem mais chance de funcionar para provedores diferentes do sistema de arquivos. O parâmetro -Include é apenas uma conveniência se você quiser filtrar os itens a serem excluídos.

É dividido em duas funções, pois acho útil ver o que estou prestes a excluir executando

Get-Tree some_dir | select fullname

Muito simples:

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

Para evitar que os erros "O diretório não está vazio" da resposta aceita, simplesmente use o bom e velho comando DOS como sugerido anteriormente. A sintaxe completa do PS pronta para copiar e colar é:

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

Por alguma razão, a resposta de John Rees às vezes não funcionou no meu caso. Mas isso me levou na seguinte direção. Primeiro tento excluir o diretório recursivamente com a opção buggy -recurse. Depois eu desço em cada subdir que resta e apago todos os arquivos.

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
        }
    }
}

Tente este exemplo. Se o diretório não existir, nenhum erro será gerado. Você pode precisar do PowerShell v3.0.

remove-item -path "c:\Test Temp\Test Folder" -Force -Recurse -ErrorAction SilentlyContinue

Use o comando DOS da velha escola:

rd /s <dir>

Outro truque útil:

Se você encontrar muitos arquivos com convenção de nome igual ou semelhante (como o arquivo mac com o nome do prefixo do ponto ... a famosa captura de arquivo), você pode facilmente removê-los com uma única linha do PowerShell assim:

ls -r .* | rm

Esta linha vai remover todos os arquivos com um ponto no início do nome dentro do diretório atual, e todos os arquivos com as mesmas circunstâncias dentro de outras pastas dentro deste diretório também. Esteja ciente disso ao usá-lo. : D


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

OU

remove-item <dir> -Recurse -Force

Se você tem um diretório enorme, então o que eu costumo fazer é

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

Execute isso em outro terminal PowerHell e ele será interrompido quando isso for feito.


rm -r <folder_name>
c:\>rm -r "my photos"

Remove-Item -Recurse -Force some_dir

funciona de fato como anunciado aqui.

rm -r -fo some_dir

são aliases abreviados que funcionam também.

Tanto quanto eu entendi, o parâmetro -Recurse simplesmente não funciona corretamente quando você tenta excluir um conjunto filtrado de arquivos de forma recursiva. Para matar um único diretório e tudo abaixo, parece funcionar bem.







delete-directory