如何删除目录中除某些文件外的所有文件?


123

我需要删除目录中的所有文件,但要排除其中一些。例如,在包含文件的目录中a b c ... z,我需要删除除u和以外的所有内容p。是否有捷径可寻?


下面的答案要好得多,但是您可以将文件设置为只读,删除所有文件,然后将其更改回其原始权限(只要不使用rm -f)。您将必须知道要还原什么权限,并且必须知道在此过程中不需要对其进行写访问。这就是为什么其他答案更好的原因。

1
如果还想删除隐藏文件,请shopt -s dotglob在运行之前运行rm (...)

Answers:


108

在这些情况下,我要做的是输入

rm *

然后我按Ctrl+ X*扩大 *到所有可见的文件名。

然后,我可以从列表中删除要保留的两个文件,最后执行命令行。


25
我猜这仅在*扩展文件列表不会太长的情况下才有效。:-}
Frerich Raabe 2013年

9
Esc后跟*还会扩展“ *”。
slowpoison 2013年

2
@SantoshKumar:对我来说这没有意义。扩展将始终有效,而不取决于您以后要使用什么命令。
Der Hochstapler

2
@OliverSalzburg对不起,这种组合有点令人困惑。我认为您应该这样写:Ctrl+ Shift+ x+*
Santosh Kumar

2
@SantoshKumar:但这不是组合。
Der Hochstapler 2013年

143

对于rmu,pbash以外的所有用户,只需键入:

rm !(u|p)

这需要设置以下选项:

shopt -s extglob

查看更多:glob-Greg的Wiki


1
您必须激活“ extglobbing”:shopt -s extglob
sparkie 2013年

18
您需要shopt -s extglob@Ashot。另外,它只是文件,而不是目录,这就是为什么我删除了-rf命令中的选项的原因。
slhck

3
如果您需要在选择的文件中排除一个文件,请尝试以下操作:rm !(index).html。这将删除所有以“ .html”结尾的文件,“ index.html”除外。
mzuther

71

您可以使用 find

find . ! -name u ! -name p -maxdepth 1 -type f -delete
  • ! 否定下一个表达式
  • -name 指定文件名
  • -maxdepth 1将使查找过程仅处理指定的目录(find默认情况下遍历目录)
  • -type f 将仅处理文件(而不是目录)
  • -delete 将删除文件

然后,您可以在find手册页上调整条件

更新资料

  • 请记住,表达式元素的顺序很重要(请参阅文档)
  • 首先使用-print而不是测试您的命令-delete

    find . ! -name u ! -name p -maxdepth 1 -type f -print

5
谓词的顺序在这里至关重要。如果看跌-delete刚过.这将是灾难(将删除CWD所有文件)
米哈尔Šrajer

可以更紧凑地写为find . -maxdepth 1 -type f -name '[^up]' -delete
kojiro

4
@kojiro是的,但仅适用于仅一个字母的文件。对于更复杂的名称,正则表达式可能会一团糟。
Matteo

2
find是我最好的朋友,尤其是当文件太多而无法继续时
Terence Johnson

43

简单:

mv您想要的文件放在较高的目录中,rm然后再mv返回目录。


13
偏离目标时,将它们移动到更高的目录。尽量不要将它们转换为要删除的子目录...
Konerak 2013年

@Konerak:rm没有,-r不会删除子目录。
reinierpost

11
这将覆盖目标目录中具有相同名称的文件
Matteo

7
我对此表示反对,因为尽管它很方便,但它也是非原子性的,可以在短时间内有效地从目录中删除所有文件;例如,如果文件在网络上共享,则这是不可接受的。
sam hocevar

15

类似于此答案,但不需要特殊选项,据我所知,以下是任何(模糊地)/ bin / sh类似shell(例如bash,zsh,ksh等)支持的“古老”功能

rm [^up]

2
这适用于1个字符的文件名。对于更长的名字,sparkie的答案更好。
格伦

3
怎么了rm [^up]*?我经常做类似的事情。
CVn 2013年

3
@MichaelKjörling-这将删除所有以u或p开头的文件,而不仅仅是名称为u和p的文件。我认为OP(@Ashot)表示az和u,p等。象征性地而不是字面上。
Sudipta Chatterjee 2013年

4
@HobbesofCalvin这将删除所有以u或p开头的文件,而不是以它们开头的文件。
rjmunro

@rjmunro-谢谢,错过了那个!:)
Sudipta Chatterjee

11

这样做找不到:

ls | grep -v '(u|p)' | xargs rm

(与此处的其他地方一样,编辑:“ u”和“ v”被用作整个正则表达式的通用版本。显然,您需要谨慎锚定正则表达式,以避免匹配太多内容。)

正如其他人所建议的那样,如果您要做很​​多事情,那么您肯定会想要脚本。


grep默认情况下不会处理扩展的regexpt:使用-E还是egrep
Matteo

2
这将排除包含u或-Matteo的所有文件p
2013年

@Matteo不,不会。grep不是grep文件,而是gs ls命令的输出。您正在考虑类似grep -L (u|p)' * | xargs rmwhere -L表示列表文件名不包含匹配项的内容。
rjmunro

4
哦,你说的是谁的名字中包含的任何文件up不包含任何文件up。那是对的。您可以使用egrep -v '^(u|p)$'
rjmunro 2013年

1
除了这些匹配项,这里是所有内容!ls | grep -v 'vuze\|progs' | xargs rm -rf
尼克

6

在zsh中:

setopt extended_glob  # probably in your .zshrc

然后

rm ^(u|p)

要么

rm *~(u|p)

第二个甚至会工作,如果你有^$histchars对历史替换,当然你可以前放一个任意水珠~


5

GLOBIGNORE采用冒号分隔的列表

GLOBIGNORE=u:p
rm *

12
这在我的shell(GNU bash 4.1.5(1))上不起作用。请务必先使用比rm测试目录中有害的内容进行测试!
CVn

3

回到软盘时代,我有一个名为“ Except”的dos可执行文件,它将临时将内容移出当前目录并执行命令,因此您可以说:

除了* .txt del *。*

删除除文本文件之外的所有内容。

作为shell脚本实现,这将是一件微不足道的事情,如果这是您可能要做的两倍以上的事情,那似乎是个好主意。


2
它使我想起了同样的事情。但是在多任务处理时代,暂时移出文件夹可能不是一个好主意:)
Sedat Kapanoglu 2013年

3
 find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

这将删除unix中除u和p以外的所有文件


2

对于那些更喜欢以完整的正则表达式emacs,posix-awk或posix扩展样式(请参阅查找手册页)指定任意复杂的排除模式(跨越所有受影响的文件名)的人,我建议您使用此模式。在此示例中,它在当前目录中不包含up。这对于脚本可能很方便。

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf

您需要在表达式之前指定目录(`find。-regextype ...)。
Matteo

-regextype将仅适用于GNU版本
Matteo,

否-如果应该使用当前目录,我的查找版本(debian squeeze)绝对不需要在表达式前使用显式目录
sparkie 2013年

@sparke:这仅适用于GNU实现
Matteo

@sparkie:未定义目录(第一个参数)findfindcommand 的GNU扩展。-regextype选项同样如此。此外,您的命令也会删除子目录中的文件,而原始问题明确询问了目录中的文件。
Mikko Rantalainen

1

我一直使用:

rm [a-o,q-t,v-z]*

这将允许您定义要制作的粒度。因此,如果您要删除o和Z文件,则可以使用:

rm [a-o,z]*

1

另一个版本使用xargs

ls -1 | grep -v do_not_delete | xargs -I files rm "files"

请注意,xargs -I正确处理包含空格的文件名是必需的。


1

完后还有:

for FILE in ./*; do if [[ $FILE != ./u* ]] || [[ $FILE != ./p* ]];then rm $FILE; fi; done;

这有点冗长,我不知道您是否可以轻松地将其变成可以轻松容纳任意数量的参数的函数,但是它运行良好。

而且它的纯bash的善良。


1

这是另一个变体。您可以输入:

rm -i *

要么:

rm --interactive *

因此,rm请您确认删除每个文件。


1

采用:

find . -type f ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
find . -type d ! -name 'u' ! -name 'p' ! -name '*.ext' -delete

为了删除所有文件,包括目录,除了u,p和.ext文件。


0

一种很难弄乱的简单方法:假设您要删除除* .pdf以外的所有内容:

mkdir tmp
mv *.pdf tmp
rm *
mv tmp/* .
rm -r tmp
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.