다른 디렉터리에 15일이 지난 파일이 있으면 해당 파일을 삭제하세요.

다른 디렉터리에 15일이 지난 파일이 있으면 해당 파일을 삭제하세요.

"/media/downloads/" 및 "/home/uploads/"라는 두 개의 폴더가 있습니다. "/home/uploads/"에 있는 경우 "/media/downloads/"에서 15년 된 파일을 삭제하고 싶습니다.

이를 수행하는 가장 좋은 스크립트는 무엇입니까?

미리 감사드립니다.

답변1

그리고 zsh:

cd /home/uploads
uploaded_files=( **/*(ND.) )
cd /media/downloads
old_downloads=( **/*(ND.m+14) )
echo rm -- ${old_downloads:*uploaded_files}

( echo실제로 파일을 삭제하려면 삭제하세요.)

/media/downloads동일한 경로에 일반 파일이 존재하는 경우 /home/uploads동일한 내용을 가지고 있는지 확인하지 않습니다.

스크립트로 보면 다음과 같습니다.

#! /bin/zsh -
die() {
  print -ru2 -C1 -- "$@"
  exit 1
}

usage() {
  die "$@" "Usage: $ZSH_SCRIPT:t [-d <days>] [-n] <srcdir> <dstdir>"       \
  ''                                                                \
  '  Removes files from <srcdir> if their age rounded down to an'   \
  '  integer number of days is strictly greater than <days> (14 by' \
  '  default). -n for dry-run'
  exit 1
}

zmodload zsh/system || die

dryrun=0 days=14
while getopts nd: o; do
  case $o in
    (n) dryrun=1;;
    (d) days=$OPTARG;;
    (*) usage;;
  esac
done

shift OPTIND-1
(( $# == 2 )) || usage
[[ $days = <0-> ]] || usage "$days is not a positive decimal integer"

src=$1 dst=$2

[[ -d $src ]] || die "$src is not a directory"
[[ -d $dst ]] || die "$dst is not a directory"

list() {
  local dir=$1 var=$2 qual=$3 err
  ERRNO=0
  () { eval $var'=( "${@#$dir/}" )'; } $dir/**/*(ND.$qual)
  if (( ERRNO )); then
    syserror -e err
    die "An error was encountered during $dir traversal: $err"
  fi
}

list $src old_in_src m+$days
list $dst all_in_dst oN
to_remove=( ${old_in_src:*all_in_dst} )

if (( dryrun )); then
  if (( $#to_remove )); then
    print -ru2 -C1 "$#old_in_src old files found in $src, out of which $#to_remove are also found in $dst:" ' - '$^to_remove
  else
    print -ru2 "No file found to remove ($#old_in_src old files in $src in total)"
  fi
else
  rm -f -- $src/$^to_remove
fi

답변2

사용 findbash:

find /media/downloads/ -type f -mtime +15 \
  -exec bash -c 'for f; do
                   f2=${f/"/media/downloads/"/}
                   test -e "/home/uploads/$f2" && delfiles+=("$f");
                 done;
                 [ -n "$delfiles" ] && printf "rm %q\n" -- "${delfiles[@]}"' bash {} +

find15일보다 오래된 모든 일반 파일을 찾아 에 인수로 전달합니다 bash. 각 파일 이름에 대해 bash는 파일 이름에서 최상위 디렉터리( /media/downloads/)를 제거한 다음 에 있는 나머지 파일 이름(있는 경우 하위 디렉터리 포함)을 확인합니다 /home/uploads/. 따라서 파일은 이름이 지정된 배열에 추가됩니다 $delfiles.

모든 파일 이름 매개변수를 반복한 후에는 배열의 각 파일 이름을 인쇄합니다.

이것은 시험 실행으로 작성되었으므로전시하다실제로 그렇게 하지 않았다면 어떻게 될까요? 실제로 파일을 삭제하려면 printf "rm %q\n" --다음으로 변경하십시오.rm --

삭제된 후 내용이 비어 있더라도 디렉터리는 절대 삭제되지 않습니다. 이 작업을 수행해야 하는 경우 파일을 삭제한 후 다음 명령(GNU find 사용)을 실행할 수 있습니다.

find /media/downloads/ -mindepth 1 -type d -empty -delete

또한 주목할 가치가 있습니다: 둘 다 zsh유사한 매개변수 확장 및 문자열 수정 기능을 가지고 있으므로 kshbash 대신 또는 사용하기가 간단해야 합니다(또는로 변경할 수도 있지만 테스트하지 않았으므로 확실히 말할 수는 없습니다. bash 및 껍질마다 약간의 차이가 있을 수 있습니다.zshkshbash -cksh -czsh -c


¹계산 방법에 대한 자세한 내용을 살펴보고 man find검색해 보세요. 자신에게 더 적합할 수도 있습니다. 관심이 있다면 찾는 옵션도 가능합니다.-atime-mtime 14-daystart

관련 정보