#!/bin/bash # 列出目錄內的所有檔案,只保留最新的n個檔案 # 使用方法: newestN.sh -d=<目錄路徑> [-n=<保留數量>] [--confirm=<0|1>] # 預設值 DIR="" KEEP_NUM=2 CONFIRM=0 # 顯示幫助訊息 show_help() { echo "用法: $0 -d=<目錄路徑> [-n=<保留數量>] [--confirm=<0|1>]" echo "" echo "參數說明:" echo " -d=<目錄路徑> 指定要處理的目錄 (必需)" echo " -n=<保留數量> 保留最新的檔案數量 (預設: 2)" echo " --confirm=<0|1> 是否需要使用者確認 (預設: 0)" echo " 0 = 不須確認,直接刪除" echo " 1 = 需要使用者確認" echo "" echo "範例:" echo " $0 -d=/backup/logs -n=5" echo " $0 -d=/backup/logs -n=3 --confirm=1" exit 1 } # 解析參數 for arg in "$@"; do case $arg in -d=*) DIR="${arg#*=}" ;; -n=*) KEEP_NUM="${arg#*=}" ;; --confirm=*) CONFIRM="${arg#*=}" ;; -h|--help) show_help ;; *) echo "錯誤: 未知的參數 '$arg'" show_help ;; esac done # 檢查目錄參數是否提供 if [ -z "$DIR" ]; then echo "錯誤: 必須提供目錄路徑" echo "" show_help fi # 檢查目錄是否存在 if [ ! -e "$DIR" ]; then echo "錯誤: 路徑 '$DIR' 不存在" echo "" show_help fi # 檢查是否為目錄 if [ ! -d "$DIR" ]; then echo "錯誤: '$DIR' 不是一個目錄" echo "" show_help fi # 檢查保留數量是否為正整數 if ! [[ "$KEEP_NUM" =~ ^[0-9]+$ ]] || [ "$KEEP_NUM" -lt 1 ]; then echo "錯誤: 保留數量必須是正整數" exit 1 fi # 檢查 confirm 參數是否有效 if [ "$CONFIRM" != "0" ] && [ "$CONFIRM" != "1" ]; then echo "錯誤: --confirm 參數必須是 0 或 1" exit 1 fi echo "處理目錄: $DIR" echo "保留最新 $KEEP_NUM 個檔案" echo "" # 取得目錄中的所有檔案(不含子目錄),按修改時間排序(最新的在前) FILES=($(find "$DIR" -maxdepth 1 -type f -printf '%T@ %p\n' | sort -rn | cut -d' ' -f2-)) # 檔案總數 TOTAL=${#FILES[@]} if [ $TOTAL -eq 0 ]; then echo "目錄中沒有檔案" exit 0 fi echo "目錄中共有 $TOTAL 個檔案" echo "" # 如果檔案數量小於或等於保留數量,不需要刪除 if [ $TOTAL -le $KEEP_NUM ]; then echo "檔案數量 ($TOTAL) 未超過保留數量 ($KEEP_NUM),無需刪除" exit 0 fi # 計算要刪除的檔案數量 DELETE_COUNT=$((TOTAL - KEEP_NUM)) echo "即將刪除 $DELETE_COUNT 個舊檔案:" echo "----------------------------------------" # 列出即將被刪除的檔案 TO_DELETE=("${FILES[@]:$KEEP_NUM}") for file in "${TO_DELETE[@]}"; do # 顯示檔案名稱和修改時間 MOD_TIME=$(stat -c '%y' "$file" | cut -d'.' -f1) echo " $file (修改時間: $MOD_TIME)" done echo "----------------------------------------" echo "" # 如果需要確認 if [ $CONFIRM -eq 1 ]; then read -p "確定要刪除以上檔案嗎? (y/N): " response case "$response" in [yY][eE][sS]|[yY]) echo "開始刪除檔案..." ;; *) echo "取消刪除操作" exit 0 ;; esac else echo "開始刪除檔案..." fi # 刪除舊檔案 DELETED=0 for file in "${TO_DELETE[@]}"; do if rm "$file" 2>/dev/null; then echo "已刪除: $file" DELETED=$((DELETED + 1)) else echo "刪除失敗: $file" fi done echo "" echo "完成! 共刪除 $DELETED 個檔案"