找不到文件夹:`./folder':没有这个文件或目录。

4
这是我正在处理的目录内容:

misha@hp-laptop:~/work/c/5$ ls -l
total 8
-rw-rw-r-- 1 misha misha  219 May 20 15:37 demo.c
drwxrwxr-x 2 misha misha 4096 May 20 16:07 folder
-rw-rw-r-- 1 misha misha    0 May 20 16:06 test

现在我想要从这个目录中删除除了文件demo.c之外的所有内容。下面是我想出来的命令:

rm -r !(demo.c)
find . ! \( -name demo.c -o -name . \) -exec rm -Rf {} \;

它确切地做了你想要它做的事情(即,文件test和目录folder被删除了),但同时也显示了以下错误信息:
find: `./folder': No such file or directory

你认为这是为什么呢?

1
尝试使用 find . -depth ... 命令,否则 find 命令会尝试进入已删除的 ./folder 文件夹。 - Stefan Hegny
3个回答

6

it also displays this error message:

find: `./folder': No such file or directory

Why is that?

因为find在首次读取目录.时,会将./folder识别为一个目录,而不是考虑它是否符合find的条件或对其执行任何操作。它无法识别该操作将删除该目录,因此在执行操作后,它尝试进入该目录以扫描其内容。然而,等到执行这个操作时,该目录已经不存在了。
有多种方法来解决这个问题。其中一种方法是使用-prune操作。这告诉find不要进入与测试匹配的目录:
find . ! \( -name demo.c -o -name . \) -exec rm -Rf {} \; -prune

这里可以使用这种方法,并且它也适用于您不删除目录并且不想限制搜索深度的领域。

此外,避免影响.的另一种方法是利用find接受多个基本路径进行测试的事实,如果您希望,这些可以指定常规文件,并且在路径名扩展期间,文件名中的任何前导.必须明确匹配。 如果在目标目录中没有点文件(除了...),则可以按以下方式完成您的目标:

find * ! -name demo.c -exec rm -Rf {} \; -prune

2
今日免费次数已满, 请开通会员/明日再来
find . -mindepth 1 -not -name demo.c -delete
  • -mindepth 1 确保您不选择DOT目录
  • -delete 将删除所有文件和目录

明白了,我应该这样写:find . -maxdepth 1 ! ( -name demo.c -o -name . ) -exec rm -Rf {} ; 我忘记加上-maxdepth 1了。 - user4087080
maxdepth 1 只会在当前目录下查找文件和目录,您仍然可以使用 mindepth 1 来避免排除 DOT。您的命令可以为:find . -mindepth 1 -maxdepth 1 -not -name demo.c -delete - anubhava

1
#before


        ls -lrt
        total 4
        -rw-rw-r--  1 user super    0 May 20 09:14 demo.c
        drwxrwxr-x  2 user super 4096 May 20 09:14 folder/
        -rw-rw-r--  1 user super    0 May 20 09:14 test


#Command
        ls -1 | grep -v demo.c |xargs rm -rf 
#After        
        ls -lrt
        total 0
        -rw-rw-r--  1 user super 0 May 20 09:14 demo.c

ls 不适合用于编程,也不安全 - 请参见 http://mywiki.wooledge.org/ParsingLs - Charles Duffy
此外,grep -v demo.c 将会排除 foo-demo.c,而 OP 的 -name demo.c 则不会;这段代码并不完全等同于它所替代的内容。 - Charles Duffy
顺便说一下,为了好玩,考虑到文件名中可能包含换行符。使用 touch $'cant\ndelete\nme' 创建的文件将不仅因为 xargs 表现不佳(它确实如此——除非使用 -0-d 等扩展,否则它是有缺陷的),而且因为 ls -1 无法在以换行符分隔的输出流中明确表示该名称而逃脱 ls -1 | grep -v demo.c | xargs rm -rf 方法。 - Charles Duffy
此外,如果文件名中有空格,例如 touch 'hello cruel world',则您提供的 xargs 用法将尝试删除三个不同的文件,即 hellocruelworld,而不是真正存在的那个文件。同样地,如果您的文件名中有引号,则 xargs 将尝试将它们视为语法上的元素。 - Charles Duffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接