如何处理三人一组的文件

How to process files in groups of three

我有一个文件夹,其中包含 3 个月和不到 1 年的备份文件。它们具有相同的名称部分,但其他部分是备份日期(所以我有一组文件)。在我的文件夹中的所有文件中,我只需要保留每个组的 3 个 zip 文件:不是所有文件的最后 3 个修改文件,而是每个组的最后 3 个文件,因为备份可以在不同的时间创建过去。其他文件,删除。

示例:

zip 文件列表:

ais_2016-02-21.zip
ais_hg_2016-07-31.zip
ais_hg_2016-08-07.zip
ais_hg_2016-08-14.zip
ais_hg_2016-08-21.zip
ais_hg_2016-08-28.zip
ais_hg_2016-09-04.zip
asf_2016-07-17.zip
asf_2016-07-24.zip
asf_2016-07-31.zip
asf_2016-08-07.zip
asf_2016-08-14.zip
asf_2016-08-21.zip
asf_2016-08-28.zip
asf_2016-09-04.zip
asf-ant-tasks_2015-12-13.zip
asf-ant-tasks_2015-12-27.zip
asf-ant-tasks_2016-01-17.zip
asf-ant-tasks_2016-01-31.zip
asf-ant-tasks_2016-02-14.zip
asf-ant-tasks_hg_2016-02-28.zip
asf-ant-tasks_hg_2016-08-07.zip
asf-ant-tasks_hg_2016-08-14.zip
asf-ant-tasks_hg_2016-08-21.zip
asf-ant-tasks_hg_2016-08-28.zip

群组:

ais
ais_hg
asf
asf-ant-tasks
asf-ant-tasks_hg

而且我需要保留 ais 的 3 个最后修改的文件、ais_hg 的 3 个、asf 的 3 个等。但是,还有更多的文件组 (130)所以我不能在脚本中手动编写每个组。

所以我来了。我有两个数组,我不知道从这里去哪里。

#!/bin/bash

files=(/media/sf/zipp/outOFtime/*.zip)
cuts=($(find ${files[@]} -type f | sed 's/.{15}$//' | sed 's/^.{1}//' | sort |uniq ))

for f in "${cuts[@]}" 
do
    echo -e $f 
done

首先,获取唯一组的列表。 (我假设文件名中没有换行符。)

for f in *.zip; do
  echo "${f%%_*}"
done | sort -u > groups.txt

接下来获取每组匹配的文件列表,只输出最后三个:

while IFS= read -r group; do
  files=( "$group"_*.zip )
  for f in "${files[@]:0:${#files[@]}-3}"; do
    rm "$f"
  done
done < groups.txt

首先,"${var:s:l}" 扩展为长度为 l 的子字符串,从 var 的值的 s 位置开始。当应用于数组时,它会扩展 l 个数组元素的序列,从索引 s 处的元素开始。所以在这里,如果 files 中有 9 个元素,那么 ${#files[@]} 扩展为 9。从中减去 3 剩下 6(sl 都是在算术上下文中计算的) ,所以我们有一个 ${files[@]:0:6} 的中间表达式。那么,结果就是数组中的前 6 个文件。