폴더를 삭제하되 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을 일주일 전 시간과 비교하여 이를 유지할지 삭제할지 결정합니다.

출력에서 올바른 디렉토리를 찾으면 해당 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을 사용하여 현재 경로의 디렉터리만 고려합니다.

관련 정보