【问题标题】:find: `./folder': No such file or directory查找:`./folder':没有这样的文件或目录
【发布时间】:2016-09-17 18:37:13
【问题描述】:

这是我正在使用的目录的内容:

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 之外的所有内容。这是我想出的命令:

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

它完全按照您的想法执行(意思是,文件test 和目录folder 消失了),但同时它也显示以下错误消息:

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

你认为这是为什么?

【问题讨论】:

  • 尝试find . -depth ...,否则find会在删除后尝试进入文件夹./folder

标签: linux bash shell unix find


【解决方案1】:

它还会显示此错误消息:

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

为什么会这样?

因为find 在首次读取目录. 时将./folder 识别为目录,然后再考虑它是否符合find 标准或对其执行任何操作。它无法识别该操作将删除该目录,因此在执行该操作后,它会尝试进入该目录以扫描其内容。但是,当它这样做时,该目录已不存在。

有多种方法可以解决这个问题。尚未提及的一项是使用-prune 操作。这告诉find 不要进入与测试匹配的目录:

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

这将在这里很好地发挥作用,并且在您不删除目录并且不想限制搜索深度的区域中也有应用程序。

此外,避免影响. 的另一种方法是利用find 接受多个基本路径来测试这一事实,如果您愿意,这些路径可以指定常规文件,并且在路径名扩展期间任何前导@文件名中的 987654331@ 必须显式匹配。如果与您的情况一样,目标目录中没有点文件(... 除外),那么您可以像这样实现您的目标:

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

【讨论】:

    【解决方案2】:

    您可以将find 命令更改为:

    find . -mindepth 1 -not -name demo.c -delete
    
    • -mindepth 1 确保不要选择 DOT
    • -delete 将删除所有文件和目录

    【讨论】:

    • 明白了。我应该这样写: find . -最大深度 1 ! ( -name demo.c -o -name . ) -exec rm -Rf {} \;我忘了 -maxdepth 1。
    • maxdepth 1 只会在当前目录中查找文件和目录,您仍然可以使用mindepth 1 来避免排除 DOT。您的命令可以是:find . -mindepth 1 -maxdepth 1 -not -name demo.c -delete
    【解决方案3】:
    #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 不适合编程使用,也不安全——请参阅mywiki.wooledge.org/ParsingLs
    • 另外,grep -v demo.c 将排除 foo-demo.c,而 OP 的 -name demo.c 不会;这段代码并不完全等同于它作为替代的代码。
    • 为了好玩,顺便说一句,考虑文件可以在其名称中包含换行符。使用touch $'cant\ndelete\nme' 创建的东西会避开ls -1 | grep -v demo.c | xargs rm -rf 方法,这不仅是因为xargs 行为不端(它确实如此——除非-0-d 等扩展,它是被设计破坏的),而且还因为@ 987654332@ 无法在换行符分隔的输出流中明确表示该名称。
    • 另外,文件名中带有空格,即。 touch 'hello cruel world',您给出的xargs 用法将尝试删除三个单独的文件,hellocruelworld,并且尝试删除实际存在的那个文件。同样,如果您的文件名称中包含引号,xargs 将尝试将它们视为语法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    • 2021-06-24
    • 2015-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多