如何处理三人一组的文件
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(s
和 l
都是在算术上下文中计算的) ,所以我们有一个 ${files[@]:0:6}
的中间表达式。那么,结果就是数组中的前 6 个文件。
我有一个文件夹,其中包含 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(s
和 l
都是在算术上下文中计算的) ,所以我们有一个 ${files[@]:0:6}
的中间表达式。那么,结果就是数组中的前 6 个文件。