【发布时间】:2011-05-14 19:25:59
【问题描述】:
使用rm *.sh 删除以 .sh 结尾的文件简单易懂。但是如何删除当前目录中不以.jar结尾的所有文件
类似rm * -except *.jar
【问题讨论】:
-
用 [Bash] =) 标记这个问题
标签: unix shell command-line terminal
使用rm *.sh 删除以 .sh 结尾的文件简单易懂。但是如何删除当前目录中不以.jar结尾的所有文件
类似rm * -except *.jar
【问题讨论】:
标签: unix shell command-line terminal
试试这个:
find . -mindepth 1 -maxdepth 1 ! -name '*.jar' | sort
如果你真的想删除其输出中的所有文件,那么就这样做
find . -mindepth 1 -maxdepth 1 ! -name '*.jar' -delete
您可以阅读 find(1) 手册页,了解有关这个非常强大的工具的更多信息。
编辑:
由于 -delete 标志仅在 GNU find > 4.2.3 中找到(如 SiegeX 所指出的),这里有几个替代方案,它们也确保我们不会尝试删除目录:
find . -mindepth 1 -maxdepth 1 ! -type d ! -name '*.jar' -print0 | xargs -0 -r rm -f
-r xargs 标志是一个 GNU 扩展,所以它的可移植性稍微好一点(它适用于 *BSD),但不是那么干净:
find . -mindepth 1 -maxdepth 1 ! -type d ! -name '*.jar' -print0 | xargs -0 rm -f
作为最后一个 - 但最便携的 - 度假村:
find . -mindepth 1 -maxdepth 1 ! -type d ! -name '*.jar' -exec rm '{}' ';'
这样做的缺点是为每个文件单独调用 rm,这会显着降低速度。
【讨论】:
-exec rm {} \; 或 -exec rm {} +。然而,使用find 来完成这个任务有点像用大锤敲碎坚果。看看我使用 shell 的 extglob 选项的答案。
extglob 也是非标准的(仅限 bash),如果你担心的话,ls 有空格问题,所以 find 是唯一的便携方式(我知道)。
-exec rm {} + 而不是通过管道连接到 xargs。 It's also POSIX
echo $(ls | grep -v '.jar$')
rm $(ls | grep -v '.jar$')
【讨论】:
ls 是您可以做的最糟糕的事情之一,将ls 解析为删除文件或文件夹的手段是您可以做的第二糟糕的事情。阅读Why you shouldn't parse the output of ls 了解原因。
您可以通过启用扩展 glob extglob 选项然后将您的模式放入 !() 中来做到这一点,如下所示:
shopt -s extglob;
rm !(*.jar)
请注意,extglob 还为您提供以下信息:
?() -- 匹配零个或一个模式*() -- 匹配零个或多个模式@() -- 完全匹配其中一种模式!() -- 匹配除模式以外的任何内容【讨论】:
[shell],所以如果他使用的是 Bourne 或 C shell,这将不起作用。