別のディレクトリに15日以上経過したファイルがある場合は、そのファイルを削除してください。

別のディレクトリに15日以上経過したファイルがある場合は、そのファイルを削除してください。

「/media/downloads/」と「/home/uploads/」という2つのフォルダがあります。 「/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の代わりにまたは使用するのは簡単です(またはに変更することはできますが、テストしていないので確かに言うことはできません)。違いがあるかもしれません。zshkshbash -cksh -czsh -c


¹計算方法の詳細を調べてman find検索してください。あなた自身にもっと適しているかもしれません。興味があれば、探すオプションも可能です。-atime-mtime 14-daystart

関連情報