删除目录中的所有文件(不要触摸任何文件夹或其中的任何文件)

我想知道rm是否可以删除目录中的所有文件(但不是子文件夹或子文件夹内的文件)?

我知道一些人使用:

 rm -f /direcname/*.* 

但是这假设文件名有一个扩展,不是所有的(我想所有的文件 – 有或没有扩展名被删除)。

尽管find可以使用-exec rm {} \;来删除文件-exec rm {} \; 您可以使用

 find /direcname -maxdepth 1 -type f -delete 

而且速度更快。 使用-delete意味着-depth选项,这意味着在目录之前处理目录内容。

 find /direcname -maxdepth 1 -type f -exec rm {} \; 

说明:

  • /direcname find文件和目录的搜索
  • -maxdepth将其限制为查找/direcname直接子项的文件和目录
  • -type f将搜索限制为文件
  • -exec rm {} \; 对每个文件运行命令rm {} (代替文件的路径替换{} )。

我想知道rm是否可以删除目录中的所有文件(但不是子文件夹或子文件夹内的文件)?

这很容易:

 $ rm folder/* 

没有-rrm命令将不会触及子目录或它们包含的文件。 这将只删除文件folder中的文件,而不是子目录或其文件。

你会看到错误告诉你, 文件夹/富是一个目录可以不能被删除,但实际上你可以。 如果你想消除这些消息,只需重定向STDERR:

 $ rm folder/* 2> /dev/null 

顺便说一句, rm命令的退出状态可能不是零,所以你不能检查rm是否有错误。 如果这很重要,你必须循环:

 $ for file in * > do > [[ -f $file ]] && rm $file > [[ $? -ne 0 ]] && echo "Error in removing file '$file'" > done 

这应该在BASH中工作,即使文件名中有空格也是如此。

您可以使用

 find /direcname -maxdepth 1 -type f -exec rm -f {} \; 

一个shell解决方案(没有非标准的find -maxdepth)将会是

 for file in .* *; do test -f "$file" && rm "$file" done 

一些shell,特别是zsh和可能是bash版本4(但不是版本3),有一个语法来做到这一点。

用zsh你可能只是输入

 rm /dir/path/*(.) 

如果你想删除名称以foo开头的文件,在子目录中递归的,你可以这样做

 rm /dir/path/**/foo*(.) 

双星的特点是(与恕我直言更好的互动完成)在我看来,足以切换到交互shell的zsh。 因人而异

括号后缀中的圆点表示您只希望zsh shell扩展文件(不是符号链接或目录)。

Unix不是DOS。 文件名中没有特殊的“扩展名”字段。 点之后的任何字符只是名称的一部分,被称为后缀。 可以有多个后缀,例如.tar.gz 。 shell glob字符*匹配整个. 字符; 它是后缀忘记。 所以MS-DOS *.*只是*在Unix中。

几乎。 *不匹配以.开头的文件. 。 按照惯例,用前导点命名的对象是“隐藏的”。 除非您指定-a ,否则它们不会显示在ls中。

(这意味着“self”和“parent”的...目录条目被认为是隐藏的。)

要匹配隐藏的条目,请使用.*

rm命令不会删除目录(当不使用-r递归操作时)。 尝试rm <directory> ,看看。 即使目录是空的,它也会拒绝。

因此,从目录中删除所有(非隐藏)文件,管道,设备,套接字和符号链接的方式(但是保留子目录)实际上是:

 rm /path/to/directory/* 

也删除隐藏的开始.

 rm /path/to/directory/{*,.*} 

这个语法是大括号扩展。 支撑扩展不是模式匹配; 在这种情况下,它只是一个产生多个参数的简单方法:

 rm /path/to/directory/* /path/to/directory/.* 

这个扩展首先发生,然后发生globbing来生成要删除的名称。

请注意,这里发布的各种解决方案有各种问题

 find /path/to/directory -type f -delete # -delete is not Unix standard; GNU find extension # without -maxdepth 1 this will recurse over all files # -maxdepth is also a GNU extension # -type f finds only files; so this neglects to delete symlinks, fifos, etc. 

即使要删除的目录条目的数量很大,GNU查找解决方案也能起作用:太大而无法将单个调用传递给rm 。 另一个好处是内置的-delete不会将有趣的路径名传递给外部命令。

针对太多目录条目问题的便携式解决方法是用ls和pipe将条目lsxargs

 ( cd /path/to/directory ; ls -a | xargs rm -- ) 

括号表示“在子过程中执行这些命令”; 这样cd的效果就被遗忘了,这在脚本中很有用。 ls -a包含隐藏的文件。

我们现在包括一个--之后的rm ,意思是“这是最后一个选项;其他的一切都是非选项论点”。 这防止我们的名字与选项无法区分的目录条目。 如果一个文件被调用了-rf并且结束了第一个参数呢? 那么你有rm -rf ...这将吹掉子目录。

简单的shell globbing会做:

 % tree . ├── 1 ├── 2 ├── 3 ├── 4 ├── 5 └── bar ├── a ├── b ├── c ├── d └── e 1 directory, 10 files % rm -f * rm: cannot remove './bar': Is a directory % tree . . └── bar ├── a ├── b ├── c ├── d └── e 1 directory, 5 files 

正如在Jens的答案中,您可能需要添加第二个rm -f .*但只有在您期望主目录中存在隐藏文件的情况下。 不需要检查类型( test -f ),因为rm -f选项不会删除目录。 然而,这也将删除“特殊”文件,如符号链接和块设备。

最简单的方法是使用:

 rm * 

为了删除目录,你必须指定选项-r

 rm -r 

所以你的目录和其中包含的任何东西都不会被删除

 rm * 

每rm的手册页,其目的是删除文件,这就是为什么这个工程