Linux 删除目录中的所有文件(不要触摸任何文件夹或其中的任何内容)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10460224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove all files in a directory (do not touch any folders or anything within them)
提问by toop
I would like to know whether rm
can remove all files within a directory (but not the subfolders or files within the subfolders)?
我想知道是否rm
可以删除目录中的所有文件(但不能删除子文件夹或子文件夹中的文件)?
I know some people use:
我知道有些人使用:
rm -f /direcname/*.*
but this assumes the filename has an extension which not all do (I want all files - with or without an extension to be removed).
但这假设文件名具有并非所有人都具有的扩展名(我希望删除所有文件 - 带或不带扩展名)。
回答by tonio
You can use
您可以使用
find /direcname -maxdepth 1 -type f -exec rm -f {} \;
回答by huon
find /direcname -maxdepth 1 -type f -exec rm {} \;
Explanation:
解释:
find
searches for files and directories within/direcname
-maxdepth
restricts it to looking for files and directories that are direct children of/direcname
-type f
restricts the search to files-exec rm {} \;
runs the commandrm {}
for each file (after substituting the file's path in place of{}
).
find
在其中搜索文件和目录/direcname
-maxdepth
将其限制为查找作为其直接子代的文件和目录/direcname
-type f
将搜索限制为文件-exec rm {} \;
rm {}
为每个文件运行命令(在用文件路径代替 之后{}
)。
回答by Jens
A shell solution (without the non-standard find -maxdepth) would be
外壳解决方案(没有非标准的 find -maxdepth)将是
for file in .* *; do
test -f "$file" && rm "$file"
done
回答by troller
Although find allows you to delete files using -exec rm {} \;
you can use
虽然 find 允许您删除文件,但-exec rm {} \;
您可以使用
find /direcname -maxdepth 1 -type f -delete
and it is faster. Using -delete implies the -depth option, which means process directory contents before directory.
而且速度更快。使用 -delete 意味着 -depth 选项,这意味着在目录之前处理目录内容。
回答by Basile Starynkevitch
Some shells, notably zshand perhaps bash version 4 (but not version 3), have a syntax to do that.
一些 shell,特别是zsh和 bash 版本 4(但不是版本 3),有一个语法来做到这一点。
With zsh you might just type
使用 zsh 你可能只需要输入
rm /dir/path/*(.)
and if you would want to remove any file whose name starts with foo, recursively in subdirectories, you could do
如果您想在子目录中递归删除名称以 foo 开头的任何文件,您可以这样做
rm /dir/path/**/foo*(.)
the double star feature is (with IMHO better interactive completion) in my opinion enough to switch to zsh for interactive shells. YMMV
双星功能(恕我直言更好的交互式完成)在我看来足以切换到 zsh 以进行交互式 shell。青年会
The dot in parenthesis suffix indicates that you want only files (not symlinks or directories) to be expanded by the zsh shell.
括号后缀中的点表示您只希望 zsh shell 扩展文件(而不是符号链接或目录)。
回答by Kaz
Unix isn't DOS. There is no special "extension" field in a file name. Any characters after a dot are just part of the name and are called the suffix. There can be more than one suffix, for example.tar.gz
. The shell glob character *
matches across the .
character; it is oblivious to suffixes. So the MS-DOS *.*
is just *
In Unix.
Unix 不是 DOS。文件名中没有特殊的“扩展名”字段。点后的任何字符只是名称的一部分,称为后缀。例如,可以有多个后缀.tar.gz
。shell glob 字符*
匹配整个.
字符;它忽略了后缀。所以 MS-DOS*.*
只是*
在 Unix 中。
Almost. *
does not match files which start with a .
. Objects named with a leading dot are, by convention, "hidden". They do not show up in ls
either unless you specify -a
.
几乎。*
不匹配以.
.开头的文件。按照惯例,用前导点命名的对象是“隐藏的”。ls
除非您指定,否则它们不会出现在任何一个中-a
。
(This means that the .
and ..
directory entries for "self" and "parent" are considered hidden.)
(这意味着“self”和“parent”的.
和..
目录条目被认为是隐藏的。)
To match hidden entries also, use .*
要匹配隐藏的条目,请使用 .*
The rm
command does not remove directories (when not operated recursively with -r
).
Try rm <directory>
and see. Even if the directory is empty, it will refuse.
该rm
命令不会删除目录(不使用 递归操作时-r
)。试试看rm <directory>
。即使目录为空,它也会拒绝。
So, the way you remove all (non-hidden) files, pipes, devices, sockets and symbolic links from a directory (but leave the subdirectories alone) is in fact:
因此,从目录中删除所有(非隐藏)文件、管道、设备、套接字和符号链接(但不要理会子目录)的方式实际上是:
rm /path/to/directory/*
to also remove the hidden ones which start with .
:
还删除以以下开头的隐藏内容.
:
rm /path/to/directory/{*,.*}
This syntax is brace expansion. Brace expansion is not pattern matching; it is just a short-hand for generating multiple arguments, in this case:
此语法是大括号扩展。大括号扩展不是模式匹配;它只是生成多个参数的简写,在这种情况下:
rm /path/to/directory/* /path/to/directory/.*
this expansion takes place first first and then globbing takes place to generate the names to be deleted.
首先进行这种扩展,然后进行通配以生成要删除的名称。
Note that various solutions posted here have various issues:
请注意,此处发布的各种解决方案都有各种问题:
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.
The GNU find solutions have the benefit that they work even if the number of directory entries to be deleted is huge: too large to pass in a single call to rm
. Another benefit is that the built-in -delete
does not have issues with passing funny path names to an external command.
GNU find 解决方案的好处是,即使要删除的目录条目数量很大,它们也能工作:太大而无法通过单个调用rm
. 另一个好处是内置程序在-delete
将有趣的路径名传递给外部命令时没有问题。
The portable workaround for the problem of too many directory entries is to list the entries with ls
and pipe to xargs
:
目录条目过多问题的可移植解决方法是使用ls
管道列出条目xargs
:
( cd /path/to/directory ; ls -a | xargs rm -- )
The parentheses mean "do these commands in a sub-process"; this way the effect of the cd
is forgotten, which is useful in scripting. ls -a
includes the hidden files.
括号的意思是“在子进程中执行这些命令”;这样cd
就忘记了 的效果,这在脚本编写中很有用。ls -a
包括隐藏文件。
We now include a --
after rm
which means "this is the last option; everything else is a non-option argument". This guards us against directory entries whose names are indistinguishable from options. What if a file is called -rf
and ends up the first argument? Then you have rm -rf ...
which will blow off subdirectories.
我们现在包含一个--
after rm
,表示“这是最后一个选项;其他所有内容都是非选项参数”。这可以保护我们免受名称与选项无法区分的目录条目的侵害。如果一个文件被调用-rf
并以第一个参数结束怎么办?然后你有 rm -rf ...
哪些会吹掉子目录。
回答by David W.
I would like to know whether rm can remove all files within a directory (but not the subfolders or files within the subfolders)?
我想知道 rm 是否可以删除目录中的所有文件(但不能删除子文件夹或子文件夹中的文件)?
That's easy:
这很容易:
$ rm folder/*
Without the -r
, the rm
command won't touch sub-directories or the files they contain. This will only remove the files in folder
and not the sub-directories or their files.
没有-r
,该rm
命令不会触及子目录或它们包含的文件。这只会删除folder
子目录中的文件,而不会删除子目录或其文件。
You will see errorstelling you that folder/foois a directory can cannot be removed, but that's actually okay with you. If you want to eliminate these messages, just redirect STDERR:
您会看到错误,告诉您folder/foo是一个无法删除的目录,但这实际上对您没问题。如果您想消除这些消息,只需重定向 STDERR:
$ rm folder/* 2> /dev/null
By the way, the exit status of the rm
command may not be zero, so you can't check rm
for errors. If that's important, you'll have to loop:
顺便说一句,rm
命令的退出状态可能不为零,因此您无法检查rm
错误。如果这很重要,你将不得不循环:
$ for file in *
> do
> [[ -f $file ]] && rm $file
> [[ $? -ne 0 ]] && echo "Error in removing file '$file'"
> done
This should work in BASH even if the file names have spaces in them.
即使文件名中有空格,这也应该在 BASH 中工作。
回答by Jon R
The easiest way to do this is to use:
最简单的方法是使用:
rm *
In order to remove directories, you must specify the option -r
为了删除目录,您必须指定选项 -r
rm -r
so your directories and anything contained in them will not be removed by using
所以你的目录和其中包含的任何东西都不会被删除
rm *
per the man page for rm, its purpose is to remove files, which is why this works
根据 rm 的手册页,它的目的是删除文件,这就是它起作用的原因