如果数量超过 15,脚本是否会删除目录中的旧文件(tar)?

如果数量超过 15,脚本是否会删除目录中的旧文件(tar)?

请问有人能给出解决方案吗?我正在尝试将 gitlab 备份到另一台服务器,如果目录中的文件数超过 15,脚本是否应该删除旧文件?

答案1

声明:我已使用包含空格的文件名测试了以下命令,但未使用包含换行符的文件名测试过。我怀疑它们无法很好地处理包含换行符的文件名,如果您怀疑可能会创建包含换行符的文件名,请避免使用它们。

此方法依赖于文件的 ctime,因此如果文件的任何属性发生变化,它们看起来都会比创建时间更新。只有您可以决定是否在您的情况下依赖 ctime。如果您更愿意使用 mtime,请在命令中更改-printf "%C+ %p\n"为。-printf "%T+ %p\n"find

以下命令可以在包含 tar 文件的目录中发出。这假设文件名都类似于something.tar。如果文件名不是这种格式,则需要修改命令,如果文件是 .tar.gz 文件,则将 更改为-iname '*.tar.',或者如果您只想对该目录中的任何文件进行操作,而不管文件名格式如何,-iname '*.tar.gz*'则删除整个字符串。-iname '*.tar.'

find . -mindepth 1 -maxdepth 1 -type f -iname '*.tar' -printf "%C+ %p\n" | sort -n | cut -d ' ' -f 2- | head -n -15 | xargs -I{} echo "{}"

如果显示的最旧文件超出了 15 个文件的限制,请使用以下命令删除这些文件。

find . -mindepth 1 -maxdepth 1 -type f -iname '*.tar' -printf "%C+ %p\n" | sort -n | cut -d ' ' -f 2- | head -n -15 | xargs -I{} rm "{}"

解释一下:

  • find . -mindepth 1 -maxdepth 1 -type f -iname '*.tar' -printf "%C+ %p\n"将列出 (当前目录) 中所有以 .tar 结尾的文件,.而不递归到子目录中。然后打印 ctime timastamp 后跟一个空格和文件名,后面跟一个换行符。
  • | sort -n按数字对输出进行排序find,因此文件按从最旧到最新的顺序列出(按 ctime)。
  • | cut -d ' ' -f 2-删除创建的添加的时间戳find,但保留列出的文件的顺序sort
  • | head -n -15从 的输出中修剪底部 15 个项目cut
  • xargs -I{} rm "{}"在每个文件上运行rm命令,确保文件名不会因空格而分割。

这可以写成一个 bash 脚本,将要保留的文件数和要操作的目录作为脚本中的变量。也可以将目录和文件保留计数作为参数传递,但我不会在这里介绍这一点。

#!/bin/bash

file_limit=15
dir=/directory/containing/tarfiles

find "$dir" -mindepth 1 -maxdepth 1 -type f -iname '*.tar' -printf "%C+ %p\n" | sort -n | cut -d ' ' -f 2- | head -n -"$file_limit" | xargs -I{} rm "{}"

如果您将此脚本保存在某处,例如,/home/user/trim_old_gits并确保已授予其可执行权限。可以通过输入以下命令从命令行运行该脚本:

/home/user/trim_old_gits

或者从内部/home/user

./trim_old_gits

正如所提到的雅各布太棒了python 答案cron,如果不需要立即删除文件,或者inotifywait时间比较敏感,则使用该实用程序将是确保定期发生这种情况的好方法。

答案2

鉴于ctime和都mtime不能保证你真的删除了最老的文件,取决于中间文件发生的情况,下面的脚本会删除给定目录内超过任意数量的文件。

(奧)这里我们可以读到:

时间是 inode 或文件更改时间。当文件属性发生更改(例如更改所有者、更改权限或将文件移动到其他文件系统)时,ctime 会更新,但当您修改文件时也会更新。mtime

时光网是文件修改时间。修改文件时,mtime 会更新。每当您更新文件内容或保存文件时,mtime 都会更新。

大多数情况下,ctime 和 mtime 是相同的,除非只更新文件属性。在这种情况下,只有 ctime 会更新。

话说回来

根据ctime文件的,如果文件数量超过设定的数量,下面的小后台脚本将删除最旧的文件。您可以自行决定这是否是您情况下可用的选项。

剧本

#!/usr/bin/env python3
import sys
import os
from operator import itemgetter
import time

dr = sys.argv[1]; n = int(sys.argv[2])

while True:
    time.sleep(3)
    # list files; get the number of files
    files = [os.path.join(dr, f) for f in os.listdir(dr)]; nfiles = len(files)
    if nfiles > n:
        # if nfiles exceeds the threshold, get the number of files to delete
        todel = nfiles - n
        # sort the list by creation date, delete the oldest
        del_list = sorted([
            [f, os.path.getctime(f)] for f in files
            ], key=itemgetter(1))[:todel]
        for f in del_list:
            os.remove(f[0])

如何使用

  1. 将脚本复制到一个空文件中,另存为keep_latest.py
  2. 测试——从终端运行脚本,使用目录路径和要保留的(最新)文件数作为参数:

    python3 '/path/to/keep_latest.py' '/path/to/directory' 15
    

    保存最新的 15 个文件'/path/to/directory'

  3. 如果一切正常,请添加到启动应用程序:Dash > 启动应用程序 > 添加。添加命令:

    python3 '/path/to/keep_latest.py' '/path/to/directory' 15
    

其他选择

上面的脚本是众多选项之一。如果mtimectime足够了,另一个选择是使用通知等待,并使其执行与上述脚本相同的操作,但是仅有的如果文件被添加、移动或复制到目录中。

如果时间准确性(立即删除多余的文件)不是很重要,那么运行命令也是cron一个不错的选择。

如果循环inotifywait或上面的脚本更有效,则会成为测试和比较的对象。

无论哪种方式,所使用的资源实际上都是零。

答案3

bash 脚本

  • 列出文件
  • 如果超过限制 => 开始删除文件,直到达到限制
# create array of files sorted on timestamp (oldest first)
rr=$(find /data/*.tgz -type f -printf '%T+ %p\n' | sort)

# if more then 7 tgz files, list the oldest files to array files_to_delete
files_to_delete=$(echo -e "$rr"| awk -v ftd="$(($(echo -e "$rr"| wc -l) - 7))" '{if(ftd<=0) exit; print $NF; if(NR==ftd)exit;}')

# delete the files
echo -e "$file_to_delete" | xargs rm -vf

相关内容