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

Ash*_*hot 127 linux bash rm

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

spa*_*kie 145

为了rm所有,但u,p在bash只需键入:

rm !(u|p)
Run Code Online (Sandbox Code Playgroud)

这需要设置以下选项:

shopt -s extglob
Run Code Online (Sandbox Code Playgroud)

查看更多:glob - Greg's Wiki

  • 你需要`shopt -s extglob`,@Ashot。此外,它只是文件,而不是目录,这就是我删除命令中的 `-rf` 选项的原因。 (18认同)
  • 如果您需要排除一个文件**选择**的文件,试试这个:`rm !(index).html`。这将删除所有以“.html”结尾的文件,“index.html”除外。 (4认同)

Der*_*ler 109

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

rm *
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我想这只有在`*` 扩展的文件列表不会变得太长时才有效。:-} (25认同)
  • Esc 后跟 * 也会扩展“*”。 (10认同)
  • @SantoshKumar:这对我来说没有意义。扩展将始终有效,它不取决于您之后要使用的命令。 (2认同)
  • @OliverSalzburg 抱歉,这个组合有点混乱。我认为你应该像`Ctrl` + `Shift` + `x` + `*` 这样写 (2认同)
  • @SantoshKumar:但这不是组合。 (2认同)

Mat*_*teo 76

您可以使用 find

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

然后,您可以查看find手册页来调整条件

更新

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

    find . ! -name u ! -name p -maxdepth 1 -type f -print
    
    Run Code Online (Sandbox Code Playgroud)

  • 谓词的顺序在这里至关重要。如果将 `-delete` 放在 `.` 之后,那将是一场灾难(将删除 CWD 中的所有文件) (5认同)
  • @kojiro 是的,但仅适用于只有一个字母的文件。对于更复杂的名称,正则表达式可能会一团糟。 (4认同)
  • `find` 是我最好的朋友,尤其是当有太多文件需要 glob 时 (2认同)

use*_*581 44

简单的:

mv把你想要的文件放在一个上层目录下,rm然后mv把它们放回目录。

  • 当然,将它们 mv 到更高的目录。尽量不要将它们 mv 到您要删除的子目录... (13认同)
  • 这将覆盖目标目录中具有相同名称的文件 (11认同)
  • 我对此表示反对,因为虽然它很方便,但它也是非原子的,可以在短时间内有效地从目录中删除所有文件;例如,如果文件在网络上共享,这是不可接受的。 (9认同)

hlo*_*dal 16

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

rm [^up]
Run Code Online (Sandbox Code Playgroud)

  • @HobbesofCalvin 这将删除所有*不*以 u 或 p 开头的文件,而不是以它们开头的文件。 (4认同)
  • `rm [^up]*` 有什么问题?我经常做类似的事情。 (3认同)
  • @MichaelKjörling - 这将删除所有以 u 或 p 开头的文件,而不仅仅是名称为 u 和 p 的文件。我认为 OP (@Ashot) 的意思是 az 和 u、p 等。象征性的,而不是字面上的。 (3认同)
  • 这适用于 1-char 文件名。对于更长的名字,sparkie 的答案更好。 (2认同)

小智 15

没有找到就这样做:

ls | grep -v '(u|p)' | xargs rm
Run Code Online (Sandbox Code Playgroud)

(编辑:“u”和“v”,就像这里的其他地方一样,被用作整个正则表达式的通用版本。显然,你需要小心地锚定你的正则表达式以避免匹配太多东西。)

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

  • 哦,你的意思是任何名称包含`u` 或`p` 的文件,而不是包含`u` 或`p` 的任何文件。那是正确的。您可以使用 `egrep -v '^(u|p)$'` 修复 (4认同)
  • 这将排除任何包含 `u` 或 `p` 的文件 (2认同)

poo*_*lie 6

在 zsh 中:

setopt extended_glob  # probably in your .zshrc
Run Code Online (Sandbox Code Playgroud)

然后

rm ^(u|p)
Run Code Online (Sandbox Code Playgroud)

或者

rm *~(u|p)
Run Code Online (Sandbox Code Playgroud)

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


W_W*_*ley 5

GLOBIGNORE 采用冒号分隔的列表

GLOBIGNORE=u:p
rm *
Run Code Online (Sandbox Code Playgroud)

  • 这在我的 shell (GNU bash 4.1.5(1)) 上不起作用。**一定要先用比 `rm`** 危害小一点的东西或在测试目录中测试它! (12认同)