我正在尝试编写一个非常简单的Bash shell脚本,该脚本将在特定目录中执行cd,它将删除除少数选定文件和目录之外的所有文件和目录,然后cd回原始目录。
我的代码是:
#!/bin/bash
cd /path/to/desired/directory
shopt -s extglob
rm !\(filename1\|filename2\|filename3\) -rf
cd -
我尝试了很多不同的方法来编写符号'('和'|',使用单引号或双引号或反斜杠但没有任何效果。请注意,shopt -s extglob
和rm !(filename1|filename2) -rf
可以正常工作脚本。
可能我提交了一个我无法看到的标准和基本的bash脚本错误,但经验即将到来......
有什么建议!? 提前谢谢。
答案 0 :(得分:8)
我可以立即看到两个问题:
-rf
的{{1}}参数必须在文件名之前 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”