Bash脚本删除除特定文件和目录之外的所有文件和目录

时间:2013-11-05 05:18:34

标签: bash shell rm

我正在尝试编写一个非常简单的Bash shell脚本,该脚本将在特定目录中执行cd,它将删除除少数选定文件和目录之外的所有文件和目录,然后cd回原始目录。

我的代码是:

#!/bin/bash 
cd /path/to/desired/directory
shopt -s extglob
rm !\(filename1\|filename2\|filename3\) -rf
cd -

我尝试了很多不同的方法来编写符号'('和'|',使用单引号或双引号或反斜杠但没有任何效果。请注意,shopt -s extglobrm !(filename1|filename2) -rf可以正常工作脚本。

可能我提交了一个我无法看到的标准和基本的bash脚本错误,但经验即将到来......

有什么建议!? 提前谢谢。

5 个答案:

答案 0 :(得分:8)

我可以立即看到两个问题:

  • -rf的{​​{1}}参数必须在文件名之前
  • extglob说明符rm!(| 不应使用反斜杠进行转义

请改为尝试:

)

如果它仍然不起作用,请删除rm -rf !(filename1|filename2|filename3) 参数,然后您将收到有关出错的错误消息,而不是静默抑制它们。要打印删除的每个文件的名称,您也可以添加-f选项。

答案 1 :(得分:3)

如果您有最新版本的find,请使用:

find . -not -regex "filename1|filename2|filename3" -print

检查输出并将-print替换为-delete,如果它只打印您确实要删除的文件。

如果您的find版本不支持-delete,请使用-type f -exec rm "{}" \;

请注意,这只会删除文件。这很重要:如果您要保留文件x但该文件位于y文件夹中,那么它将忽略x仅稍后将整个文件夹{{1}删除}。

要删除所有空文件夹(并保留您要保留的文件):

y

(来源:How to Find and Delete Empty Directories and Files in Unix

答案 2 :(得分:0)

尝试以下:

for i in `ls | grep -v "file1\|file2\|file3"` ; do rm -rf $i; done

祝你好运!

答案 3 :(得分:0)

我不建议尝试编写规则来豁免特定文件。我更可能做的是尝试在你想要删除的文件的名称中找到filemask / glob或其他一些锚点,这些文件是你想保留的文件所没有的。在大多数情况下,你可以通过扩展来做到这一点。不幸的是,因为你没有提到任何文件的名称,我不能更具体地帮助你。

像两个(或更多)找到循环的东西: -

find *.mp3 d.mp3 -maxdepth 1 -type f | while read mp3s
do
mv $mp3s ~/d.stuff-to-keep
done    

find *.txt d.mp3 -maxdepth 1 -type f while read textfiles
do
rm -v $textfiles
done

如果没有,请查找文件的其他常见特征。如果没有,您可能需要重命名文件以给自己一个。我总是在我的文件名中放置很多锚点(分隔的名称字段,扩展名等),因为这样我有很多不同的方法来做我需要的东西。我通常的名称格式是: -

<extension>.+<author>+<year>+<work-name>+<volume-number>+<number-of-volumes>

加号是字段分隔符,短划线用于空格,但没有破折号作为第一个或最后一个字符。允许使用全部小写字母,无控制字符或其他非字母数字。因此,我可以使用awk,cut或其他任何我想要使用的东西来剪切它们,并轻松地重命名它们。将扩展名放在名称的开头,也意味着ls只需要一个标志(-l)来获得完美排序的文件系统。

如果您知道如何将目录结构用作具有基本POSIX工具的数据库,则有时您不需要安装任何更复杂的内容,以便做您想做的事。

您在UNIX中对文件名有一个长字符限制,以及用于浏览长名称的标签完成。不要害怕自由地使用它们。

答案 4 :(得分:0)

假设您有文件:

  

drwxr-xr-x 2 root root 4096 Feb 1 02:17 a

     

drwxr-xr-x 2 root root 4096 Feb 1 02:17 b

     

drwxr-xr-x 2 root root 4096 Feb 1 02:17 c

     

drwxr-xr-x 2 root root 4096 Feb 1 02:17 d

     

drwxr-xr-x 2 root root 4096 Feb 1 02:17 e

     

drwxr-xr-x 2 root root 4096 Feb 1 02:17 f

     

drwxr-xr-x 2 root root 4096 Feb 1 02:18 nodelete1

     

drwxr-xr-x 2 root root 4096 Feb 1 02:18 nodelete2

你可以这样做:

ls | grep -v "nodel.\+" | xargs rm -rf

使用高级正则表达式语法排除文件。

说明:

ls ---列出当前目录(ls -d仅列出目录)

grep -v --- v flag指定了什么不匹配+ grep允许写入perl样式regexp如果你提供-P标志

xargs ---对每个项目施加行动“rm -rf”