【问题标题】:BASH Script - Delete folders older than X days except for some and all their subfolders/filesBASH 脚本 - 删除超过 X 天的文件夹,但部分和所有子文件夹/文件除外
【发布时间】:2017-07-09 12:39:01
【问题描述】:

我实际上是在测试这个脚本

find /Path/Folder/* -type d -mtime +7 ! -path "/Path/Folder/NODELETE1/*"  ! -path "/Path/Folder/NODELETE2/*"  ! -path "/Path/Folder/NODELETE3/*" -exec rm -rf {} \;

删除所有超过 7 天的文件/文件夹,NODELETE1NODELETE2NODELETE3 文件夹除外。

问题是它显然不起作用,因为它会删除这些文件夹和里面的所有文件。

这就是我想做的:

我有

/Path/Folder/NODELETE1/some files and folders
/Path/Folder/NODELETE2/some files and folders
/Path/Folder/NODELETE3/some files and folders
/Path/Folder/AFOLDER/somefiles and folders
/Path/Folder/ANOTHERFOLDER/somefiles and folders
/Path/Folder/...
/Path/Folder/FILE
/Path/Folder/ANOTHERFILE
/Path/Folder/...

我想自动删除所有超过 7 天的文件和文件夹(FOLDERANOTHERFOLDER...FILEANOTHERFILE...)这样

/Path/Folder/NODELETE1/some files and folders
/Path/Folder/NODELETE2/some files and folders
/Path/Folder/NODELETE3/some files and folders

脚本有什么问题?

使用脚本建议编辑:

#!/bin/bash

while IFS= read -r -d '' dir
do

    # This line actually halts the control from entering if 
    # dirname contains either of the three names below. You could
    # remove it and put your actual folder names.

    [[ $dir =~ ^(NODELETE1|NODELETE2|NODELETE3)$ ]] && continue

    # Suggest un-commenting the echo line below and comment rm to ensure
    # you have only the folders you want to delete. 
    echo "$dir"

    # rm -rf "$dir"     
done< <(find /Users/Username/Desktop/test/* -type d -mtime +7 -print0)

为了测试,我有:

/Users/Username/Desktop/test/NODELETE1
/Users/Username/Desktop/test/NODELETE2
/Users/Username/Desktop/test/NODELETE3
/Users/Username/Desktop/test/YESDELETE

和脚本路径

/Users/Username/Desktop/TEST.sh

【问题讨论】:

  • 你可以试试-not -path "/Path/Folder/NODELETE1/*"而不是! -path "/Path/Folder/NODELETE1/*"
  • 只有我患有偏执狂,永远不会直接执行rm -rf作为find -exec的参数? :)
  • @jm666:这里也一样,这就是为什么建议使用正确名称检查的替代方法

标签: bash directory except


【解决方案1】:

TL;DR 修复:

代替你的线,做:

find /Path/Folder/* -type d -mtime +7 ! -path "/Path/Folder/NODELETE1"  ! -path "/Path/Folder/NODELETE2"  ! -path "/Path/Folder/NODELETE3" -exec rm -rf {} \;

更长的解释:

-type d 部分仅搜索目录。但是您要排除的是您的 NODELETE 目录中的内容。这仍然意味着您的 NODELETE 目录是 rm -rf 的目标,因此它们会被递归删除。

【讨论】:

    【解决方案2】:

    我建议不要依赖find 命令的核心工具,而是让bash 处理它(无论如何你已经标记了bash)以排除具有特定名称的文件夹,

    #!/bin/bash
    
    while IFS= read -r -d '' dir
    do
    
        # This line actually halts the control from entering if 
        # dirname contains either of the three names below. You could
        # remove it and put your actual folder names.
    
        [[ $dir =~ ^(NODELETE1|NODELETE2|NODELETE3)$ ]] && continue
    
        # Suggest un-commenting the echo line below and comment rm to ensure
        # you have only the folders you want to delete. 
        # echo "$dir"
    
        rm -rf "$dir"     
    done< <(find /Path/Folder/* -type d -mtime +7 -print0)
    

    【讨论】:

    • 它给了我这个错误line 17: syntax error near unexpected token /Users/Username/Desktop/TEST.sh : line 17: done&lt; &lt;(find /Users/Username/Desktop/test/* -type d -mtime +7 -print0)'
    • @DylanDog:您是否使用 bash 解释器集运行它? #!/bin/bash 在脚本顶部?
    • @DylanDog:你可以试试我的更新吗,|| 被替换为&amp;&amp;,之前是一个错误!
    • @DylanDog:你也可以在问题中发布完整的脚本吗?包括我的逻辑,很容易指出问题
    • 我会检查我做错了什么,我会在这里报告我的错误。如果我可以将多个答案标记为最好的答案,我会心甘情愿地这样做。您的答案当然是最好的解决方案,但现在我将下面的答案标记为解决方案。非常感谢您的帮助!
    【解决方案3】:

    逃脱!作为

     \! -path
    

    确保它不会被解释为模式

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      • 2014-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多