【发布时间】:2011-08-05 07:05:39
【问题描述】:
如果我们想删除我们使用的所有文件和目录,rm -rf *。
但是如果我想一次性删除所有文件和目录,除了一个特定的文件?
有什么命令吗? rm -rf * 提供了一次删除的便利,但甚至删除了我最喜欢的文件/目录。
提前致谢
【问题讨论】:
如果我们想删除我们使用的所有文件和目录,rm -rf *。
但是如果我想一次性删除所有文件和目录,除了一个特定的文件?
有什么命令吗? rm -rf * 提供了一次删除的便利,但甚至删除了我最喜欢的文件/目录。
提前致谢
【问题讨论】:
find可以是很好的朋友:
$ ls
a/ b/ c/
$ find * -maxdepth 0 -name 'b' -prune -o -exec rm -rf '{}' ';'
$ ls
b/
$
解释:
find * -maxdepth 0: 选择* 选择的所有内容,而不降级到任何目录
-name 'b' -prune:不要打扰 (-prune) 任何符合条件 -name 'b'
-o -exec rm -rf '{}' ';':其他一切都请致电rm -rf
顺便说一句,另一种可能更简单的方法是移动或重命名您的 favourite 目录,使其不碍事:
$ ls
a/ b/ c/
$ mv b .b
$ ls
a/ c/
$ rm -rf *
$ mv .b b
$ ls
b/
【讨论】:
find * -maxdepth 0 -name 'b' -prune -o -exec rm -rf {} \;
xargs,而不是使用-exec为每个匹配生成rm?
xargs 变体没有-0,这在处理空白时往往会使事情变得更容易。
简答
ls | grep -v "z.txt" | xargs rm
详情:
上述命令的思考过程是:
例子
如下图创建5个文件:
echo "a.txt b.txt c.txt d.txt z.txt" | xargs touch
列出除 z.txt 以外的所有文件
ls|grep -v "z.txt"
a.txt
b.txt
c.txt
d.txt
我们现在可以使用 xargs 实用程序删除(rm)列出的文件:
ls|grep -v "z.txt"|xargs rm
【讨论】:
您可以直接在命令行中键入它或在脚本中使用此按键
files=`ls -l | grep -v "my_favorite_dir"`; for file in $files; do rm -rvf $file; done
附:我建议-i 切换为rm 以防止删除重要数据。
P.P.S 你可以根据这个解决方案编写小脚本并将其放置到/usr/bin(例如/usr/bin/rmf)。现在您可以将其用作普通应用程序:
rmf my_favorite_dir
脚本看起来像(只是一个草图):
#!/bin/sh
if [[ -z $1 ]]; then
files=`ls -l`
else
files=`ls -l | grep -v $1`
fi;
for file in $files; do
rm -rvi $file
done;
【讨论】:
for 循环会遇到包含空格的文件名问题...
至少在zsh中
rm -rf ^filename
如果您只想保留一个文件,可以选择。
【讨论】:
如果它只是一个文件,一种简单的方法是将该文件移动到/tmp 或其他东西,rm -Rf 目录,然后将其移回。您可以将其别名为一个简单的命令。
另一种选择是先执行 find 然后 grep 删除您不想要的内容(使用 -v 或直接使用 finds 谓词之一),然后 rming 其余文件.
对于单个文件,我会做前者。除此之外,我会写一些类似于 thkala 所说的自定义内容。
【讨论】:
在 bash 中,您有 !() glob 运算符,它反转匹配的模式。所以要删除文件my_file_name.txt以外的所有内容,试试这个:
shopt -s extglob
rm -f !(my_file_name.txt)
查看这篇文章了解更多详情: http://karper.wordpress.com/2010/11/17/deleting-all-files-in-a-directory-with-exceptions/
【讨论】:
我不知道有这样的程序,但我过去一直想要它。基本语法是:
IFS='
' for f in $(except "*.c" "*.h" -- *); do
printf '%s\n' "$f"
done
我想到的程序有三种模式:
-e)glob 匹配(默认,如上例所示)-r)它需要从命令行中排除的模式,后跟分隔符--,然后是文件名。或者,可以从stdin 读取文件名(如果给出了选项-s),每个文件名都在一行中。
这样的程序应该不难用 C 或 Shell 命令语言编写。它为学习 Unix 基础知识提供了很好的练习。当然,当您作为 shell 程序执行此操作时,您必须注意包含空格和其他特殊字符的文件名。
【讨论】:
find 的简单包装器
cp 除了.svn 之外的一些文件,也许我想呼应他们的名字。 find 的问题在于它不知道所有系统上的 -maxdepth 选项。见pubs.opengroup.org/onlinepubs/009695399/utilities/find.html。
我在这里看到了很多冗长的方法,这很有效,但是 a/ b/ c/ d/ e/
rm -rf *.* !(b*)
这将删除除目录 b/ 及其内容之外的所有内容(假设您的文件位于 b/. 然后只需 cd b/ 和
rm -rf *.* !(filename)
删除所有其他内容,但要保留的文件(名为“文件名”)。
【讨论】:
mv subdir/preciousfile ./
rm -rf subdir
mkdir subdir
mv preciousfile subdir/
这看起来很乏味,但是相当安全
rm -rf *,它的结果取决于您当前的目录(可能是/ ;-)*:它的扩展受限于 ARGV_MAX。【讨论】:
cd ..
ln trash/useful.file ./
rm -rf trash/*
mv useful.file trash/
【讨论】:
trash 与 . 位于不同的文件系统上
您需要为此使用正则表达式。编写一个正则表达式,选择除您需要的文件之外的所有其他文件。
【讨论】: