Bash

如何根據文件名中的日期刪除舊備份?

  • March 27, 2019

我有一個這樣命名的每日備份:

yyyymmddhhmm.zip // pattern
201503200100.zip // backup from 20. 3. 2015 1:00

我正在嘗試創建一個腳本來刪除所有超過 3 天的備份。該腳本還應該能夠刪除文件夾中與模式不匹配的所有其他文件(但腳本中會有一個開關來禁用此功能)。

為了確定文件年齡,我不想使用備份時間戳,因為其他程序也會對文件進行操作,並且可能會被篡改。

借助:刪除 UNIX 中超過 5 天的文件(文件名中的日期,而不是時間戳) 我得到了:

#!/bin/bash

DELETE_OTHERS=yes
BACKUPS_PATH=/mnt/\!ARCHIVE/\!backups/
THRESHOLD=$(date -d "3 days ago" +%Y%m%d%H%M)

ls -1 ${BACKUPS_PATH}????????????.zip |
 while read A DATE B FILE
 do
    [[ $DATE -le $THRESHOLD ]] && rm -v $BACKUPS_PATH$FILE
 done

if [ $DELETE_OTHERS == "yes" ]; then
   rm ${BACKUPS_PATH}*.* // but I don't know how to not-delete the files matching pattern
fi

但它一直在說:

rm: missing operand

問題出在哪里以及如何完成腳本?

您的程式碼中的第一個問題是您正在解析ls. 這意味著它很容易中斷,例如,如果您的文件或目錄名稱中有任何空格。您應該使用 shell globbing 或find代替。

更大的問題是您沒有正確讀取數據。你的程式碼:

ls -1 | while read A DATE B FILE

永遠不會填充$FILE。的輸出ls -1只是一個文件名列表,因此,除非這些文件名包含空格,否則只會read填充您提供的 4 個變數中的第一個。

這是您的腳本的工作版本:

#!/usr/bin/env bash

DELETE_OTHERS=yes
BACKUPS_PATH=/mnt/\!ARCHIVE/\!backups
THRESHOLD=$(date -d "3 days ago" +%Y%m%d%H%M)

## Find all files in $BACKUPS_PATH. The -type f means only files
## and the -maxdepth 1 ensures that any files in subdirectories are
## not included. Combined with -print0 (separate file names with \0),
## IFS= (don't break on whitespace), "-d ''" (records end on '\0') , it can
## deal with all file names.
find ${BACKUPS_PATH} -maxdepth 1 -type f -print0  | while IFS= read -d '' -r file
do
   ## Does this file name match the pattern (13 digits, then .zip)?
   if [[ "$(basename "$file")" =~ ^[0-9]{12}.zip$ ]]
   then
       ## Delete the file if it's older than the $THR
       [ "$(basename "$file" .zip)" -le "$THRESHOLD" ] && rm -v -- "$file"
   else
       ## If the file does not match the pattern, delete if 
       ## DELETE_OTHERS is set to "yes"
       [ $DELETE_OTHERS == "yes" ] && rm -v -- "$file"
   fi
done

引用自:https://unix.stackexchange.com/questions/191632