我想知道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/*
没有-r
, rm
命令将不会触及子目录或它们包含的文件。 这将只删除文件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将条目ls
到xargs
:
( 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的手册页,其目的是删除文件,这就是为什么这个工程