如何使用PowerShell 2.0递归删除整个目录?
在 PowerShell 中强制删除目录及其所有子目录的最简单方法是什么?我在 Windows 7 中使用 PowerShell V2。
我从多个来源了解到,最明显的命令 Remove-Item $targetDir -Recurse -Force
无法正常工作。这包括 PowerShell V2 在线帮助中的一条语句(使用 Get-Help Remove-Item -Examples
找到),其中指出:
...由于此 cmdlet 中的 Recurse 参数有错误,因此该命令使用 Get-Childitem cmdlet 来获取所需的文件,并使用管道运算符将它们传递给 Remove-Item cmdlet...
我见过各种示例使用 Get-ChildItem 并将其通过管道传输到 Remove-Item,但这些示例通常会根据过滤器删除某些文件集,而不是整个目录。
我正在寻找最干净的方法来清除整个目录、文件和子目录,而不使用最少量的代码生成任何用户警告消息。如果能很容易理解的话,一句台词就更好了。
What is the simplest way to forcefully delete a directory and all its subdirectories in PowerShell? I am using PowerShell V2 in Windows 7.
I have learned from several sources that the most obvious command, Remove-Item $targetDir -Recurse -Force
, does not work correctly. This includes a statement in the PowerShell V2 online help (found using Get-Help Remove-Item -Examples
) that states:
...Because the Recurse parameter in this cmdlet is faulty, the command uses the Get-Childitem cmdlet to get the desired files, and it uses the pipeline operator to pass them to the Remove-Item cmdlet...
I have seen various examples that use Get-ChildItem and pipe it to Remove-Item, but the examples usually remove some set of files based on a filter, not the entire directory.
I am looking for the cleanest way to blow out an entire directory, files and child directories, without generating any user warning messages using the least amount of code. A one-liner would be nice if it is easy to understand.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(22)
确实如此处所宣传的那样工作。
也是有效的速记别名。
据我了解,当您尝试递归删除一组已过滤的文件时,
-Recurse
参数无法正常工作。对于杀死一个目录及其下面的所有内容似乎工作正常。does indeed work as advertised here.
are shorthand aliases that work too.
As far as I understood it, the
-Recurse
parameter just doesn't work correctly when you try deleting a filtered set of files recursively. For killing a single dir and everything below it seems to work fine.我用过:
这对我来说就像一个魅力(我从 Ubuntu 中偷来的)。
I used:
This works for me like a charm (I stole it from Ubuntu).
当使用简单的
Remove-Item "folder" -Recurse
递归删除文件时,我有时会看到间歇性错误:[folder] 无法删除,因为它不为空。
这个答案尝试通过单独删除文件来防止该错误。
一个重要的细节是使用 pspath -Descending 对所有项目进行排序,以便在根之前删除叶子。排序是在
pspath
参数上完成的,因为它更有可能为文件系统以外的提供程序工作。如果您想过滤要删除的项目,-Include
参数只是一个方便的选择。它分为两个函数,因为我发现通过运行查看要删除的内容很有用
When deleting files recursively using a simple
Remove-Item "folder" -Recurse
I sometimes see an intermittent error :[folder] cannot be removed because it is not empty.
This answer attempts to prevent that error by individually deleting the files.
An important detail is the sorting of all the items with
pspath -Descending
so that the leaves are deleted before the roots. The sorting is done on thepspath
parameter since that has more chance of working for providers other than the file system. The-Include
parameter is just a convenience if you want to filter the items to delete.It's split into two functions since I find it useful to see what I'm about to delete by running
...为我工作
...worked for me
如果您致力于使用 powershell,则可以使用它,如已接受的答案中所述:
但我发现使用 Windows 命令提示符更快
除了速度更快之外,使用命令提示符选项的另一个优点是它会立即开始删除文件(powershell 首先进行一些枚举),因此如果在运行时出现问题,您至少在删除文件方面取得了一些进展。
If you're committed to powershell, you can use this, as explained in the accepted answer:
But I've found it to be faster to use Windows Command Prompt
In addition to being faster, another advantage to using the command prompt option is that it starts deleting files immediately (powershell does some enumeration first), so if something breaks while it's running, you've at least made some progress in deleting files.
试试这个例子。如果该目录不存在,则不会引发错误。您可能需要 PowerShell v3.0。
Try this example. If the directory does not exist, no error is raised. You may need PowerShell v3.0.
使用老式的 DOS 命令:
Use the old-school DOS command:
为了避免接受答案的“目录不为空”错误,只需使用之前建议的旧 DOS 命令即可。可供复制粘贴的完整 PS 语法为:
To avoid the "The directory is not empty" errors of the accepted answer, simply use the good old DOS command as suggested before. The full PS syntax ready for copy-pasting is:
由于某种原因,约翰·里斯的回答有时对我的情况不起作用。但它引导我走向以下方向。
首先,我尝试使用 buggy -recurse 选项递归删除目录。然后我进入剩下的每个子目录并删除所有文件。
For some reason John Rees' answer sometimes did not work in my case. But it led me in the following direction.
First I try to delete the directory recursively with the buggy -recurse option. Afterwards I descend into every subdir that's left and delete all files.
或者
如果你有一个巨大的目录,那么我通常会
在另一个 powershell 终端上运行它,完成后它将停止。
OR
If you have a huge directory then what I usually do is
Run this on another powershell terminal and it will stop when it is done.
删除整个文件夹树有时有效,有时会失败并出现“目录不为空”错误。随后尝试检查该文件夹是否仍然存在可能会导致“访问被拒绝”或“未经授权的访问”错误。我不知道为什么会发生这种情况,尽管可以从 这篇 StackOverflow 帖子 中获得一些见解。
我已经能够通过指定删除文件夹中的项目的顺序并添加延迟来解决这些问题。以下内容对我来说运行良好:
Microsoft TechNet 文章 使用计算的属性 PowerShell 中的功能对我获取按深度排序的子文件夹列表很有帮助。
与 RD /S /Q 类似的可靠性问题可以通过在 RD /S /Q 之前运行 DEL /F /S /Q 来解决如有必要,再次运行RD - 最好在中间暂停(即使用ping,如下所示)。
Deleting an entire folder tree sometimes works and sometimes fails with "Directory not empty" errors. Subsequently attempting to check if the folder still exists can result in "Access Denied" or "Unauthorized Access" errors. I do not know why this happens, though some insight may be gained from this StackOverflow posting.
I have been able to get around these issues by specifying the order in which items within the folder are deleted, and by adding delays. The following runs well for me:
A Microsoft TechNet article Using Calculated Properties in PowerShell was helpful to me in getting a list of sub-folders sorted by depth.
Similar reliability issues with RD /S /Q can be solved by running DEL /F /S /Q prior to RD /S /Q and running the RD a second time if necessary - ideally with a pause in between (i.e. using ping as shown below).
我采取了另一种受上面 @john-rees 启发的方法 - 特别是当他的方法在某些时候开始对我失败时。基本上递归子树并按路径长度对文件进行排序 - 从最长到最短删除
关于 -LiteralPath 魔法,这里有另一个可能会击中您的问题: https://superuser.com/q/212808
I took another approach inspired by @john-rees above - especially when his approach started to fail for me at some point. Basically recurse the subtree and sort files by their path-length - delete from longest to the shortest
Regarding the -LiteralPath magic, here's another gotchya that may be hitting you: https://superuser.com/q/212808
由于底层文件系统是异步的,因此似乎存在
Remove-Item -Force -Recurse
在 Windows 上间歇性失败的问题。 这个答案似乎解决了这个问题。该用户还积极参与 GitHub 上的 Powershell 团队。There seems to be issues where
Remove-Item -Force -Recurse
can intermittently fail on Windows because the underlying filesystem is asynchronous. This answer seems to address it. The user has also been actively involved with the Powershell team on GitHub.虽然 rm -r 会产生良好的结果,但以下方法更快:
要测试这一点,您可以轻松创建一个包含 X 文件的文件夹(我使用: 磁盘工具快速生成文件)。
然后使用以下命令运行每个变体:
我的测试文件夹上的结果是:
结果各不相同,但在我的系统上,获胜者是 fileSystemObject。我建议在目标文件系统上进行测试,看看哪种方法最适合您。
while rm -r yields good results, the following method is faster:
To test this you can easily create a folder with X files (I used: Disk Tools to quickly generate the files).
And then run each of the variants using:
the results on my test folder were:
The results vary but on my system the winner was the fileSystemObject. I recommend testing this on the target file system to see which method is the best for you.
在 PowerShell
$profile
中添加自定义函数:这是
rm -rf
行为的最准确表示。Add a custom function in your PowerShell
$profile
:This is the most accurate representation of
rm -rf
behavior.另一个有用的技巧:
如果您发现许多具有相同或相似名称约定的文件(例如带有点前缀名称的 mac 文件...那个著名的文件 pulltion),您可以轻松地用一行删除它们从 powershell 中,如下所示:
此行将删除当前目录中名称开头带有点的所有文件,以及该目录中其他文件夹中具有相同情况的所有文件。使用时要注意这一点。 :D
Another useful trick:
If you find a lot of files with same or similar name convention (like mac file with dot prefix name... that famous file pulltion), you can easily remove them with one single line from the powershell like this:
This line is going to remove all files with a dot in the begining of the name inside the current directory, and all files with same circumstances inside other folders inside this directory too. Be aware about it when using it. :D
要删除包括文件夹结构在内的完整内容,请使用
添加到
remove-item
的-recurse
确保禁用交互式提示。To delete the complete contents including the folder structure use
The
-recurse
added toremove-item
ensures interactive prompts are disabled.非常简单:
Really simple:
基于 @John Rees 的 回答并进行了一些改进。
初始文件树。 /f
代码
输出
树 . /f
Based on @John Rees's answer with some improvements.
Initial files tree . /f
Code
Output
tree . /f
请尝试以下 powershell 脚本。如果遇到诸如“Remove-Item:重解析点缓冲区中存在的标记无效”之类的错误,此脚本将跳到下一个文件/文件夹。
Please try the below powershell script. This script will skip to the next file/folder if got stuck with some error like "Remove-Item : The tag present in the reparse point buffer is invalid."
编写上面的内容来清理一些日志文件而不删除父目录,这非常有效!
Wrote the above to clean some logfiles without deleting the parent directory and this works perfectly!