rm -rf所有文件和所有隐藏文件,不带。&..错误


82

rm -rf /some/path/* 删除该目录(和子目录)中的所有非隐藏文件。

rm -rf /some/path/.* 删除该目录中的所有隐藏文件(但不删除子目录),并给出以下错误/警告:

rm: cannot remove directory: `/some/dir/.'
rm: cannot remove directory: `/some/dir/..'

在不接收有关.和的警告/错误的情况下,递归删除目标目录中所有隐藏和非隐藏的文件和文件夹的正确方法是什么..

Answers:


39

您可以随时将错误消息发送给 /dev/null

rm -rf /some/path/.* 2> /dev/null

你也可以

rm -rf /some/path/
mkdir /some/path/

...那么您一开始就不必担心隐藏文件。


2
但是,如果我只想删除隐藏的文件怎么办?
CMCDragonkai 2014年

@CMCDragonkai应该是一个不同的问题,但是您可以在Gilles的答案中找到解决方案(rm ..?* .[!.]*应该这样做)。
evilsoup 2014年

15
如果不删除并重新创建目录,则存在文件权限之后使用权限不正确的风险(在服务器环境中尤其重要)。谁能自动创建具有与以前相同权限的文件夹?
Yo Ludke 2015年

1
@YoLudke你是完全正确的,在很多情况下都没有关系,但是删除文件夹并重新创建在语义上并不等同于清空该文件夹。所以要小心!
托马斯

并非总是可以删除目录。在我的情况下,该目录是docker卷,尽管我可以在该卷内执行任何操作,但无法从容器内更改该卷本身。
dovidweisz

85

*匹配所有非点文件,.[!.]*匹配除之外的所有点文件.和名称以开头的文件..,并..?*匹配除以外的所有点文件..。它们一起匹配除.和以外的所有文件..。如果这三种模式中的任何一种都不匹配,它就会扩展为自身。rm -f不关心不存在的参数,所以这无关紧要。

rm -rf ..?* .[!.]* *

您也可以使用find。这比较复杂,但是即使有太多文件,上面的通配符也会超出系统的命令行长度限制,但仍具有工作优势。

find . -name . -o -prune -exec rm -rf -- {} +

您可能会发现清除和重新创建目录更加清晰。这具有优点(或缺点,视情况而定),即使另一个程序正在原始目录中同时创建文件,也会导致目录为空。


8
这应该是可接受的答案,因为它可以防止父级遍历和可能的删除。
rbellamy

find即使未成功删除某些文件,备用方法也会返回“成功”。不利于脚本。
富兰克林·于

关于第二条find命令,查找状态的联机帮助页“由于-delete意味着-depth,因此不能有效地同时使用-prune和-delete”。-您使用-prune -delete吗?
Doktor J

@DoktorJ确实,-prune在这里什么也没做。在回读时,我发现我没有正确回答问题:我注意不要递归,但是这个问题明确要求递归删除。我已经纠正了我的答案。
吉尔斯

2
@haylem在zsh中,您需要编写.[^.]*而不是.[!.]*在启用历史记录替换时(默认情况下是交互式的,但在脚本中不是这种情况)编写,因为zsh解析!为历史记录引用。但是在zsh中,您并不需要它,您只需要在通配符匹配中*(D)包含点文件(不带...)即可。
吉尔斯

21

刚意识到这是大多数Linux发行版中最方便的方法:

ls -A1 | xargs rm -rf

哪里

-A=列出 .以外的所有内容..

-1 =将所有项目放在一行中


4
我看到的缺点是:您需要“ cd”进入目录才能执行此操作。
kumar

ls -A1 /your/path/ | xargs rm -rf应该适用
godzillante

nope..it无济于事-例如:ls -A1〜/ test / | xargs rm -rf此命令删除我当前“ cd进入”的文件..不在目录〜/ test中。
kumar

5
如果任何文件名包含空格,换行符,引号或反斜杠,则将无法使用。
斯特凡Chazelas

1
-1由于上面的评论。↑↑↑↑↑↑↑↑
某物


4

这应该像@Gilles答案一样工作,但更紧凑:

rm -rf {,.[!.],..?}*

要么

rm -rf dir/to/files/{,.[!.],..?}*

if为了安全起见,还应该在脚本中添加for用法:

if [ -d "$DIR" ]; then
    rm -rf ${DIR}/{,.[!.],..?}*
fi

1
奇怪的是,作为Ubuntu 16.04 LTS上的bash别名,先前的答案无效。但是,alias cleandir='rm -rf {,.[!.],..?}*'确实如此。
史蒂文·文蒂米利亚

3

查找是您的朋友。

find ! -name '.' ! -name '..' -delete

% find ! -name '.' ! -name '..'
./test
./test4
./test4/.test6
./test3
./.test5
./test2
% find ! -name '.' ! -name '..' -delete    
% find ! -name '.' ! -name '..'     
%             

如果要递归搜索当前目录($ PWD)之外的其他内容,则在find命令后添加路径;例如find /path ! -name '.' ! -name '..' -delete。如果只想n降低目录数,请-maxdepth n/path参数后使用该选项。

上面的命令已经在Ubuntu 13.04系统上进行了测试。可能会在其他现代linux系统上工作。


删除当前目录中的所有目录,您可以执行find . ! -name '.' ! -name '..' -type d -delete
Andy

2

在不收到有关的警告/错误的情况下,递归删除目标目录中所有隐藏和非隐藏的文件和文件夹的正确方法是什么。和..?

假设相关目录为./dir,则

rm -rf ./dir

./dir递归地删除中的所有文件,包括隐藏的文件和目录,并包括./dir目录本身。

如果您不想删除目录本身,则可以稍后再创建它,或者使用

find ./dir -mindepth 1 -delete

或者,如果您find不支持-delete

find ./dir -mindepth 1 -depth -exec rm -rf {} ';'

使用-mindepth 1可以保留顶级目录./dir


这应该被标记为最佳答案
kiting克里斯

1

我建议你尝试一下

可关ON (隐藏文件)

  • dotglob

    shopt -s dotglob

可关

  • 未设定 dotglob

    shopt -u dotglob

这种方法工作完全按照我希望副本唯一缺少的隐藏目录命令。

    shopt -s    dotglob
    cp    -rvn  ./$from/*  ./$too/
    shopt -u    dotglob

所以我做了一个删除(删除),哎呀 ...

    shopt -s    dotglob
    rm -fr ../message_splitter--044a/*
    shopt -u    dotglob

... 也可以!

在我看来,亲爱的读者看不到message_splitter目录。无论如何,它都有一个.svn需要删除并复制到其中的文件夹。

man页面 ...

dotglob 如果设置,bash将包含以“。”开头的文件名。扩展路径名的结果。

参考资料:


-2

试试这个代码:

Dirlist=``find /some/path/ -type d -name '.[^.]*'`
for HiddenDir in $Dirlist
do
    rm -rf $HiddenDir
done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.