我需要删除目录中的所有文件,但要排除其中一些。例如,在包含文件a b c ... z的目录中,我需要删除除up之外的所有文件。有简单的方法可以做到吗?

评论

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

#1 楼

在这种情况下,我要做的是键入

rm *


,然后按Ctrl + X *,将*扩展为所有可见的文件名。

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

评论


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

–弗里希·拉贝(Frerich Raabe)
13年1月8日在16:57

Esc后跟*也会展开“ *”。

–慢毒
2013年1月9日20:45



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

–霍赫斯塔普勒(Der Hochstapler)
13年1月17日在18:18

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

– Santosh Kumar
13年1月18日在5:22

@SantoshKumar:但这不是组合。

–霍赫斯塔普勒(Der Hochstapler)
13年1月18日在11:26

#2 楼

要对b43中除rm以外的所有字符进行键入,请输入:

rm !(u|p)


这需要设置以下选项:

shopt -s extglob


查看更多:glob-Greg的Wiki

评论


您必须激活“ extglobbing”:shopt -s extglob

–sparkie
2013年1月8日13:07



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

–slhck
2013年1月8日13:07



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

–mzuther
15年7月24日在21:46



#3 楼

您可以使用find

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




!否定下一个表达式

-name指定文件名

-maxdepth 1将仅使查找过程处理指定的目录(默认情况下,find遍历目录)

-type f将仅处理文件(而不是目录)

-delete将删除文件

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

Update



请记住表达式元素的顺序很重要(请参见文档)

首先使用-print而不是-delete测试您的命令

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




评论


谓词的顺序在这里至关重要。如果在–之后删除一个。这将是灾难(将删除CWD中的所有文件)

–MichałŠrajer
13年1月8日在17:34

这可以更紧凑地写为find。 -maxdepth 1 -type f -name'[^ up]'-删除

– kojiro
13年1月8日在18:09

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

–马特奥
13年1月8日在20:15

找到是我最好的朋友,尤其是当文件太多而无法继续时

–特伦斯·约翰逊(Terence Johnson)
2013年1月9日在22:36

+1解释所有参数

– Mohan Munisifreddy
20-04-28在19:20

#4 楼

简单:

mv想要在较高目录中的文件,rm该目录,然后mv将它们返回。

评论


偏离路线时,将它们移动到更高的目录。尽量不要将它们播放到要删除的子目录中...

–科尼拉克
2013年1月8日19:21

@Konerak:不带-r的rm不会删除子目录。

– reinierpost
2013年1月8日23:07

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

–马特奥
13年1月9日在9:29

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

–sam hocevar
13年10月10日在12:19

另外,您还需要在父目录上具有写访问权限,而在共享Web服务器上可能没有该访问权限。

– Jan Heinrich Reimer
20年4月4日在20:57

#5 楼

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

rm [^up]


评论


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

–格伦·杰克曼
13年1月8日在15:31

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

–用户
13年1月8日在15:33

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

– Sudipta Chatterjee
13年1月9日在9:07

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

– rjmunro
2013年1月9日在10:48



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

– Sudipta Chatterjee
2013年1月9日在16:49

#6 楼

这样做而没有找到:

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


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

如果您打算做很多这样的事情,那么您肯定会想要一个脚本,就像其他人一样建议。

评论


默认情况下,grep将不处理扩展的regexpt:使用-E或egrep

–马特奥
13年9月9日在9:28

这将排除任何包含u或p的文件

–马特奥
13年9月9日在9:28

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

– rjmunro
13年1月9日在10:52

哦,您的意思是任何名称包含u或p的文件,而不是任何包含u或p的文件。那是对的。您可以使用egrep -v'^(u | p)$'进行修复

– rjmunro
13年1月9日,12:40

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

–尼克
2014-09-25 12:32

#7 楼

在zsh中:

setopt extended_glob  # probably in your .zshrc


然后

rm ^(u|p)




rm *~(u|p)


即使您在历史记录替换中的^中有$histchars,第二个函数也将起作用,当然,您可以在~前面放置一个任意的glob。

#8 楼

GLOBIGNORE采用冒号分隔的列表

GLOBIGNORE=u:p
rm *


评论


这在我的shell(GNU bash 4.1.5(1))上不起作用。确保首先使用比rm有害的东西或在测试目录中进行测试!

–用户
13年1月8日在20:09

#9 楼

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

except *.txt del *.*


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

将其作为shell脚本实现是一件非常琐碎的事情,如果是这种事情,您可能会做两次以上的工作将是一个好主意。

评论


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

– Sedat Kapanoglu
13年9月9日在9:18

#10 楼

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


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

#11 楼

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

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


评论


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

–马特奥
13年1月9日在9:25

-regextype仅适用于GNU版本

–马特奥
13年1月9日在9:26

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

–sparkie
2013年1月9日在9:44



@sparke:这仅适用于GNU实现

–马特奥
13年1月9日在9:48

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

– Mikko Rantalainen
2015年9月4日在5:28

#12 楼

还有一个:

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


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

这是纯bash的优点。

#13 楼

我一直使用:

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


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

rm [a-o,z]*


#14 楼

使用xargs的另一个版本:

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


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

#15 楼

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

rm -i *


或:

rm --interactive *


所以rm会要求您确认删除每个文件。

#16 楼

使用:

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


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

#17 楼

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

mkdir tmp
mv *.pdf tmp
rm *
mv tmp/* .
rm -r tmp