简体   繁体   English

使用find - 删除除任何一个之外的所有文件/目录(在Linux中)

[英]Using find - Deleting all files/directories (in Linux ) except any one

If we want to delete all files and directories we use, rm -rf * . 如果我们要删除我们使用的所有文件和目录, rm -rf *

But what if i want all files and directories be deleted at a shot, except one particular file? 但是如果我想要删除所有文件和目录,除了一个特定的文件,该怎么办?

Is there any command for that? 那有什么命令吗? rm -rf * gives the ease of deletion at one shot, but deletes even my favourite file/directory. rm -rf *一次性易于删除,但删除了我喜欢的文件/目录。

Thanks in advance 提前致谢

find can be a very good friend: find可以成为一个非常好的朋友:

$ ls
a/  b/  c/
$ find * -maxdepth 0 -name 'b' -prune -o -exec rm -rf '{}' ';'
$ ls
b/
$ 

Explanation: 说明:

  • find * -maxdepth 0 : select everything selected by * without descending into any directories find * -maxdepth 0 :选择一切由选择*没有下降到任何目录

  • -name 'b' -prune : do not bother ( -prune ) with anything that matches the condition -name 'b' -name 'b' -prune :不要打扰( -prune )任何符合条件-name 'b'

  • -o -exec rm -rf '{}' ';' : call rm -rf for everything else :为其他一切调用rm -rf

By the way, another, possibly simpler, way would be to move or rename your favourite directory so that it is not in the way: 顺便说一句,另一种可能更简单的方法是移动或重命名你喜欢的目录,这样它就不会这样:

$ ls
a/  b/  c/
$ mv b .b
$ ls
a/  c/
$ rm -rf *
$ mv .b b
$ ls
b/

Short answer 简短的回答

ls | grep -v "z.txt" | xargs rm

Details : 细节

The thought process for the above command is : 上述命令的思考过程是:

  • List all files (ls) 列出所有文件(ls)
  • Ignore one file named "z.txt" (grep -v "z.txt") 忽略一个名为“z.txt”的文件(grep -v“z.txt”)
  • Delete the listed files other than z.txt (xargs rm) 删除z.txt以外的列出文件(xargs rm)

Example

Create 5 files as shown below: 创建5个文件,如下所示:

echo "a.txt b.txt c.txt d.txt z.txt" | xargs touch

List all files except z.txt 列出除z.txt以外的所有文件

ls|grep -v "z.txt"

a.txt
b.txt
c.txt
d.txt

We can now delete(rm) the listed files by using the xargs utility : 我们现在可以使用xargs实用程序删除(rm)列出的文件:

ls|grep -v "z.txt"|xargs rm

At least in zsh 至少在zsh中

rm -rf ^filename

could be an option, if you only want to preserve one single file. 如果您只想保留一个文件,可以选择一个选项。

You can type it right in the command-line or use this keystroke in the script 您可以在命令行中键入它,也可以在脚本中使用此键击

files=`ls -l | grep -v "my_favorite_dir"`; for file in $files; do rm -rvf $file; done

PS I suggest -i switch for rm to prevent delition of important data. PS我建议-i切换rm以防止重要数据的删除。

PPS You can write the small script based on this solution and place it to the /usr/bin (eg /usr/bin/rmf ). PPS您可以根据此解决方案编写小脚本并将其放在/usr/bin (例如/usr/bin/rmf )。 Now you can use it as and ordinary app: 现在您可以将它用作普通应用程序:

rmf my_favorite_dir

The script looks like (just a sketch): 脚本看起来像(只是草图):

#!/bin/sh

if [[ -z $1 ]]; then
    files=`ls -l`
else
    files=`ls -l | grep -v $1`
fi;

for file in $files; do
    rm -rvi $file
done;

In bash you have the !() glob operator, which inverts the matched pattern. 在bash中你有!() glob运算符,它反转匹配的模式。 So to delete everything except the file my_file_name.txt , try this: 因此要删除除文件my_file_name.txt之外的所有内容,请尝试以下操作:

shopt -s extglob
rm -f !(my_file_name.txt)

See this article for more details: http://karper.wordpress.com/2010/11/17/deleting-all-files-in-a-directory-with-exceptions/ 有关详细信息,请参阅此文章: http//karper.wordpress.com/2010/11/17/deleting-all-files-in-a-directory-with-exceptions/

If it's just one file, one simple way is to move that file to /tmp or something, rm -Rf the directory and then move it back. 如果它只是一个文件,一种简单的方法是将该文件移动到/tmp或其他东西, rm -Rf目录然后将其移回。 You could alias this as a simple command. 您可以将其命名为简单命令。

The other option is to do a find and then grep out what you don't want (using -v or directly using one of find s predicates) and then rm ing the remaining files. 另一种选择是做一个find ,然后grep出来你不想要的东西(使用-v或直接使用的一个find小号谓语),然后rm荷兰国际集团剩余的文件。

For a single file, I'd do the former. 对于单个文件,我会做前者。 For anything more, I'd write something custom similar to what thkala said. 除此之外,我还会写一些类似于thkala所说的定制。

I see a lot of longwinded means here, that work, but with a/ b/ c/ d/ e/ 我看到很多longwinded的意思,这个工作,但有一个/ b / c / d / e /

 rm -rf *.* !(b*) 

this removes everything except directory b/ and its contents (assuming your file is in b/. Then just cd b/ and 这将删除除目录b /及其内容之外的所有内容(假设您的文件位于b /。然后只需cd b /和

rm -rf *.* !(filename) 

to remove everything else, but the file (named "filename") that you want to keep. 删除其他所有内容,但要保留的文件(名为“filename”)。

mv subdir/preciousfile  ./
rm -rf subdir
mkdir subdir
mv preciousfile subdir/

This looks tedious, but it is rather safe 这看起来很乏味,但相当安全

  • avoids complex logic 避免复杂的逻辑
  • never use rm -rf * , its results depend on your current directory (which could be / ;-) 从不使用rm -rf * ,其结果取决于您当前的目录(可能是/ ;-)
  • never use a globbing * : its expansion is limited by ARGV_MAX. 从不使用globbing * :它的扩展受到ARGV_MAX的限制。
  • allows you to check the error after each command, and maybe avoid the disaster caused by the next command. 允许您在每个命令后检查错误,并可能避免下一个命令引起的灾难。
  • avoids nasty problems caused by space or NL in the filenames. 避免文件名中由空格或NL引起的令人讨厌的问题。
cd ..
ln trash/useful.file ./
rm -rf trash/*
mv useful.file trash/

I don't know of such a program, but I have wanted it in the past for some times. 我不知道这样的程序,但我过去曾经想过它一段时间。 The basic syntax would be: 基本语法是:

IFS='
' for f in $(except "*.c" "*.h" -- *); do
  printf '%s\n' "$f"
done

The program I have in mind has three modes: 我想到的程序有三种模式:

  • exact matching (with the option -e ) 完全匹配(使用选项-e
  • glob matching (default, like shown in the above example) glob匹配(默认,如上例所示)
  • regex matching (with the option -r ) 正则表达式匹配(使用选项-r

It takes the patterns to be excluded from the command line, followed by the separator -- , followed by the file names. 它需要从命令行中排除模式,然后是分隔符-- ,后跟文件名。 Alternatively, the file names might be read from stdin (if the option -s is given), each on a line. 或者,可以从stdin读取文件名(如果给出选项-s ),每个都在一行上。

Such a program should not be hard to write, in either C or the Shell Command Language. 使用C语言或Shell命令语言编写这样的程序应该不难。 And it makes a good excercise for learning the Unix basics. 它是学习Unix基础知识的一个很好的练习。 When you do it as a shell program, you have to watch for filenames containing whitespace and other special characters, of course. 当你将它作为shell程序执行时,你必须注意包含空格和其他特殊字符的文件名。

you need to use regular expression for this. 你需要使用正则表达式。 Write a regular expression which selects all other files except the one you need. 编写一个正则表达式,选择除所需文件之外的所有其他文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM