仅删除文件和提示目录

时间:2014-06-18 09:30:21

标签: linux bash shell rm

当我在Linux机器上删除许多过时的文件树时,我想知道是否有一种简单的方法可以在仅提示目录的情况下递归删除文件。

我可以使用rm -ri但是有一些文件会让每个文件都很烦人。对我来说真正重要的是在文件夹上提示更多地控制发生的事情。

我不是bash专家所以我在问是否有一种简单的方法可以做到这一点。

以下是我使用长bash脚本的尝试:

#!/bin/bash

promptRemoveDir()
{
  fileCount=$(ls -1 $1 | wc -l)
  prompt=1
  while [ $prompt == 1 ]
  do
    read -p "remove directory: $1($fileCount files) ? [yl]: " answer
      case $answer in
        [yY])
          rm -r $1
          prompt=0
          ;;
        l)
          echo $(ls -A $1)
          ;;
        *)
          prompt=0
          ;;
      esac
  done
}

removeDir()
{
  if [ "$(ls -A $1)" ]
  then dirs=$(find $1/* -maxdepth 0 -type d)
  fi

  if [[ -z $dirs ]]
  then
    promptRemoveDir $1
  else
    for dir in $dirs
    do
      removeDir $dir
    done
    promptRemoveDir $1
  fi
}

for i in $*
do
  if [ -d $i ]
  then
    removeDir $i
  else
    rm $i
  fi
done

3 个答案:

答案 0 :(得分:1)

如果我理解你的问题,这应该有效

Dirs=$(find . -type d)

仅删除指定目录中的文件

for i in "$Dirs"; do read -p "Delete files in "$i": ";if [[ $REPLY == [yY] ]]; then find $i -maxdepth 1 -type f | xargs -0 rm  ; fi ;done

如果你想删除文件夹,这将从最低目录(低于它)向上读取。

for i in $(echo "$Dirs" | sed '1!G;h;$!d' ); do read -p "Delete files in $i: ";if [[ $REPLY == [yY] ]]; then rm -r "$i"; fi ;done

答案 1 :(得分:0)

这是我的简化版。无需使用lsfind

#!/bin/bash

shopt -s nullglob
shopt -s dotglob

function remove_dir_i {
    local DIR=$1  ## Optional. We can just use $1.
    local SUBFILES=("$DIR"/*) FILE
    for (( ;; )); do
        read -p "Remove directory: $DIR (${#SUBFILES[@]} files)? [YNLQ]: "
        case "$REPLY" in
        [yY])
            echo rm -fr "$DIR"
            return 0
            ;;
        [nN])
            for FILE in "${SUBFILES[@]}"; do
                if [[ -d $FILE ]]; then
                    remove_dir_i "$FILE" || return 1
                # else
                #   ## Apparently we skip deleting a file. If we do this
                #   ## we could actually simplify the function further
                #   ## since we also delete the file at first loop.
                #   # echo "Removing file \"$FILE.\""
                #   # rm -f "$FILE"
                fi
            done
            return 0
            ;;
        [lL])
            printf '%s\n' "${SUBFILES[@]}"
            ;;
        [qQ])
            return 1
            ;;
        # *)
        #   echo "Please answer Y(es), N(o), L(ist) or Q(uit)."
        #   ;;
        esac
    done
}

for FILE; do
    if [[ -d $FILE ]]; then
        remove_dir_i "$FILE"
    else
        # echo "Removing file \"$FILE.\""
        echo rm -f "$FILE"
    fi
done

当您确定它已经正常工作时,从echo命令中删除rm。测试:

rm -f /tmp/tar-1.27.1/ABOUT-NLS
rm -f /tmp/tar-1.27.1/acinclude.m4
rm -f /tmp/tar-1.27.1/aclocal.m4
rm -f /tmp/tar-1.27.1/AUTHORS
Remove directory: /tmp/tar-1.27.1/build-aux (12 files)? [YNLQ]: n
Remove directory: /tmp/tar-1.27.1/build-aux/snippet (5 files)? [YNLQ]: n
rm -f /tmp/tar-1.27.1/ChangeLog
rm -f /tmp/tar-1.27.1/ChangeLog.1
rm -f /tmp/tar-1.27.1/config.h.in
rm -f /tmp/tar-1.27.1/configure
rm -f /tmp/tar-1.27.1/configure.ac
rm -f /tmp/tar-1.27.1/COPYING
Remove directory: /tmp/tar-1.27.1/doc (25 files)? [YNLQ]: n
Remove directory: /tmp/tar-1.27.1/gnu (358 files)? [YNLQ]: n
Remove directory: /tmp/tar-1.27.1/gnu/uniwidth (2 files)? [YNLQ]: n
rm -f /tmp/tar-1.27.1/INSTALL
Remove directory: /tmp/tar-1.27.1/lib (19 files)? [YNLQ]: 
...

答案 2 :(得分:0)

实际上我刚刚遇到了find命令的-depth选项,这正是我想要的。我简直不敢相信我错过了:

  

-depth在目录本身之前处理每个目录的内容。 -delete动作也暗示-depth。

与@ Jidder的代码类似,我可以这样写:

dirs=$(find ./test_script -depth -type d); for i in $dirs; do read -p "Delete files in $i?  " REPLY; if [[ $REPLY == [yY] ]]; then rm -r $i; fi; done;

为了更具可读性:

dirs=$(find ./test_script -depth -type d)

for i in $dirs 
do 
    read -p "Delete files in $i? " REPLY
    if [[ $REPLY == [yY] ]]
    then rm -r $i
    fi
done;