删除文件夹但保留 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

stat将输出 mtime 和文件夹名称。
然后,按 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。谢谢Stéphane 的回答在这里演示连接^运算符,此处将单引号字符串附加@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

我使用了 maxdepth 1,因此它只会考虑当前路径中的目录。

相关内容