如何以三个为一组处理文件

时间:2016-09-14 11:26:40

标签: arrays bash sorting find uniq

我有一个包含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

我需要保留3个最后修改过的文件来自ais,3个来自ais_hg,3来自asf,等等。但是,还有更多的文件组(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

1 个答案:

答案 0 :(得分:1)

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

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的子字符串,从s的值var开始。应用于数组时,它会扩展一系列l数组元素,从索引s处的元素开始。所以在这里,如果files中有9个元素,那么${#files[@]}会扩展为9.从此中减去3 6(在算术上下文中计算sl) ,所以我们有一个${files[@]:0:6}的中间表达式。结果是,数组中的前6个文件。