【问题标题】:Bash delete all folders except one that might be nestedBash 删除除可能嵌套的文件夹之外的所有文件夹
【发布时间】:2021-11-20 13:39:10
【问题描述】:

我正在尝试找出一种方法来删除所有文件夹但保留一次,即使它是嵌套的。

./release/test-folder
./release/test-folder2
./release/feature/custom-header
./release/feature/footer

如果我运行类似:

    shopt -s extglob
    rm -rf release/!(test-folder2)/

or
    find ./release -type d -not -regex ".*test-folder2.*" -delete

没问题,但在路径像feature/footer这样嵌套的情况下

两个命令行都匹配 release/feature 并被删除。

您能否建议任何其他选项来保留该文件夹,无论它是多么嵌套?

【问题讨论】:

    标签: recursion directory find


    【解决方案1】:

    这不是最好的解决方案,但它确实有效。

    # $1 = root path
    # $2 = pattern
    findex(){
      # create temp dir                                                                       
      T=$(mktemp -d)
      # find all dirs inside "$1"
      # and save it in file "a"
      find "$1" -type d >$T/a
      # filtering file A by pattern "$2"
      # and save it in file "b" 
      cat $T/a | grep "$2" >$T/b
      # For each path in the file b
      # add paths of the parent directories
      # and save it in file "c"
      cat $T/b | while read P; do 
        echo $P 
        while [[ ${#1} -lt ${#P} ]]; do 
          P=$(dirname "$P")
          echo $P
        done
      done >$T/c
      # make list in file "c" unique
      # and save it in file "d"
      cat $T/c | sort -u >$T/d;
      # find from list "a" all the paths 
      # that are missing in the list "d"
      awk 'NR==FNR{a[$0];next} !($0 in a)' $T/d $T/a
      # remove temporary directory
      rm -rf $T
    }
    # find all dirs inside ./path except matching "pattern"
    # and remove it
    findex ./path "pattern" | xargs -L1 rm
    

    测试一下

    findex(){
      T=$(mktemp -d)
      find "$1" -type d >$T/a
      cat $T/a | grep "$2" >$T/b
      cat $T/b | while read P; do 
        echo $P 
        while [[ ${#1} -lt ${#P} ]]; do 
          P=$(dirname "$P")
          echo $P
        done
      done >$T/c
      cat $T/c | sort -u >$T/d;
      # save result in file "e"
      awk 'NR==FNR{a[$0];next} !($0 in a)' $T/d $T/a >$T/e
      # output path of temporary directory
      echo $T
    }
    cd $TMPDIR
    for I in {000..999}; do 
      mkdir -p "./test/${I:0:1}/${I:1:1}/${I:2:1}"; 
    done
    T=$(findex ./test "5")
    cat $T/a | wc -l  # => 1111 dirs total
    cat $T/d | wc -l  # => 382  dirs matched
    cat $T/e | wc -l  # => 729  dirs to delete
    rm -rf $T ./test
    

    【讨论】:

    • 同样的问题 find ./release -type d | grep -v "feature/footer" | xargs -L1 rm 将匹配文件夹 ./release/feature 并将删除所有内容
    猜你喜欢
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 1970-01-01
    相关资源
    最近更新 更多