Shell 脚本用于删除不同文件夹中特定类型的所有文件(最新 10 个除外)

Shell 脚本用于删除不同文件夹中特定类型的所有文件(最新 10 个除外)

首先,请原谅我的英语不好。

我正在尝试编写一个 shell 脚本来清理备份文件夹中某些类型的文件。

我需要删除某些类型的文件,除了每个文件夹中最新的 10 个文件。

文件夹结构如下:

Root folder
├── folder_1
│   ├── file_1.txt
│   └── file_2.txt
│   └── file_n.txt
├── folder_2
│   ├── file_1.txt
│   └── file_2.txt
│   └── file_n.txt
├── folder_n
│   ├── file_1.txt
│   └── file_2.txt
│   └── file_n.txt

我使用了来自大卫·福斯特作为基础,但无法弄清楚如何使其在不同的文件夹中分别工作,而无需在脚本中手动写入每个文件夹名称。

目前,脚本如下所示:

find /volume1/rootfolder/ -type f -name *.txt -printf '%T@ %p\0' |
sort --zero-terminated --reverse --numeric-sort --field-separator=' ' --key 1,1 |
gawk -F ' ' -v RS='\0' -v ORS='\0' -v retain_count=10 \
  'BEGIN{ maxage = systime() - retain_younger_days * 24 * 3600; }
  (NR > retain_count) && (int($1) < maxage) { print(substr($0, length($1) + 2)); }' |
xargs -r0 -- rm --

但问题是,它会删除所有文件夹中的所有文件,只保留最新的 10 个文件。因此,总的来说,所有文件夹中只有 10 个文件,而不是每个文件夹中都有 10 个文件。

请帮我弄清楚如何编写脚本来分别处理每个文件夹。

答案1

你将其分为两部分。首先,你构建一个目录结构,在这种情况下,我们只需要包含文件的目录。在第二部分中,我们首先对最新文件进行排序,并跳过带有 的文件tail

#!/bin/bash

while IFS= read -rd ''; do
    find "$REPLY" \
    -maxdepth 1 -type f -name '*.txt' -printf '%T@\t%p\0' | sort -zk1rn | cut -zf2- | tail -zn +$((10+1)) | xargs -r -0 echo rm
done < <( \
    find $PWD/data \
    -mindepth 2 -type f -printf %h\\0 | sort -zu \
)

也可以globstar使用for-loop

#!/bin/bash
shopt -s globstar nullglob

for a in data/*/**/; do
    find "$a" \
    -maxdepth 1 -type f -name '*.txt' -printf '%T@\t%p\0' | sort -zk1rn | cut -zf2- | tail -zn +$((10+1)) | xargs -r -0 echo rm
done

最后,我们利用计数器数组来跟踪文件数量:

#!/bin/bash

find $PWD/data -mindepth 1 -type f -name '*.txt' -printf '%T@\t%p\0' \
    | sort -zk1rn | cut -zf2- \
    | awk -F / -vRS='\0' -vORS='\0' '{a=$0; NF=NF-1} b[$0]++ >= 10 {print a}' | xargs -r -0 echo rm

相关内容