フォルダを削除しますが、7日前の最新フォルダ20個を保持します。

フォルダを削除しますが、7日前の最新フォルダ20個を保持します。

7日以上のフォルダを削除しますが、常に最新のフォルダを20個保持する方法を探しています。 _SAME_NAME_@tmpに似た名前のフォルダも削除する必要があります。

私はそれが20個のフォルダになるようにし、月が過ぎても削除されないようにしなければならないと主張します。私はまだ入れ子になったwhileループ構文のために苦労しています。よろしくお願いします。

#!/bin/bash

folders=`ls -A /folder/folder1  | sort -n > /tmp/test.txt`
NUMofFolders=`wc -l /tmp/test.txt | awk '{print $1}'`

if [ $NUMofFolders -lt 20 ] ;
then
 echo "Only 20 folders exist"
 exit 1
else
echo "Runing with the script"

fi

input="/tmp/test.txt"
FolderPATH="/folder/folder1"
count=$(find $Folders -maxdepth 1 -type d -mtime +7 -printf '%Ts\t%P\n' -exec egrep -v "*@tmp" '{}' + | wc -l)

while IFS= read -r line ;
do
while [ "$count" -gt "20" ] ;
do
  find /folder/folder1/"$line" -maxdepth 1 -type d -mtime +7 -printf '%Ts\t%P\n' {} \;
      do
        find $FolderPATH -maxdepth 1 -type d -mtime +7 -print -delete -quit
        count=$((--count))
        rm -rf $FolderPATH@tmp

      done
  done < "$input"

答え1

stat以下を使用してディレクトリの実行時間を取得する必要があります。解析されないls

seven_days=$(date -d '7 days ago' '+%s')
stat -c "%Y %%n" /folder/folder1/*/ | sort -nr | tail -n +20 | while read -r mtime name; do
    if (( mtime < seven_days )); then
        echo "remove directory $name"
    fi
done

statmtimeとフォルダ名が出力されます。
次に、mtimeに基づいて最新の項目から古い項目までソートします。
その後、最初の20件の結果を無視します。
その後、ループはフォルダのmtimeを1週間前の時間と比較して、それを保持するか削除するかを決定します。

出力で正しいディレクトリを見つけたら、そのecho行を変更して実際に削除します。

答え2

タグ付けされたものを見ました。ただし、zshがオプションの場合、このzshスクリプトを使用すると操作が簡単になる可能性があります。

zmodload zsh/mapfile
startingdirs=( ${(f)mapfile[/tmp/test.txt]} )
for dir in $startingdirs
do
  deleteme=( $dir/*(N/m+7om[21,-1]) )
  rm -r $deleteme $^deleteme'@tmp'
done

これでmapfile関数がロードされます(クレジット取引)は、入力ファイル/tmp/test.txtの開始ディレクトリのリストを配列に読み込みます。次に、対応する開始ディレクトリ配列を繰り返し、削除する候補ディレクトリの他の配列を初期化します。削除するディレクトリのリストは、開始ディレクトリの下にワイルドカードセットを展開した結果です。「グローバル予選」:

  • N- このパターンにNULL_GLOBオプションを設定します。一致するファイルがない場合(たとえば、十分に古いファイルがないため)、結果の配列は空になります。
  • /- ディレクトリの一致を制限します。
  • m+7- 7日以上前に変更された項目に一致を制限します。
  • om- 修正時刻に基づいて最新の項目から古い項目の順に結果リストを「並べ替え」または並べ替えます。
  • [21,-1]- 結果リストの一部を項目21からリストの最後に分割して、項目20の後に最も古いファイルを作成します。

rm -r次に、そのリストに拡張子を追加して結果ディレクトリのリストを呼び出します@tmp。ありがとうステファンの答えはここにあります^一重引用符で囲まれた文字列が@tmp配列の各要素に追加される接続演算子を示します。

答え3

数回の痛みを伴う繰り返しの終わりに、ついに私に合った解決策を見つけました。

#!/bin/bash

# Inserting folders names in a file by reverse order - new at the starnputt
ls -A /tmp/lab  | egrep -v "*@tmp" | sort -nr > /tmp/test.txt

# Removing 20 newst folders.
sed '1,20d' /tmp/test.txt > /tmp/new_removed.txt

# Checking if there are more than 20 folders, if not- exit.
NUMofFolders=`wc -l /tmp/new_removed.txt | awk '{print $1}'`

if [ $NUMofFolders -lt 20 ] ;
then
 echo "Only 20 folders exist"
 exit 1
else
echo "Running with the script"

fi

#Deleting files, after checking it is older than 7 days
input="/tmp/new_removed.txt"
FolderPATH="/tmp/lab"

while IFS= read -r line ;
do
if [[ $(find "$FolderPATH/$line" -maxdepth 1 -type d -mtime +7 -print -exec rm -rf {} +) ]]; then
echo "files Deleted"

fi
done < "$input"

unset NUMofFolders
unset input
unset FolderPATH
unset line

答え4

次のスクリプトが機能します。

#!/bin/bash
count=`find . -maxdepth 1 -type d | wc -l`
if [[ $count > 20 ]]
then
  under_7days=`find . -maxdepth 1 -type d -daystart -mtime -7 | wc -l`
  if [[ $under_7days >= 20 ]]
  then
    find . -maxdepth 1 -daystart -mtime +7 -exec rm -rvf {} \;
  else
    echo "Since total directories which created under 7 days is $under_7days"
  fi
elif [[ $count <= 20 ]]
then
  echo "Number of folders exsists in the path is $count"
fi

私はmaxlength 1を使用して現在のパスのディレクトリのみを考慮します。

関連情報