Предположим, что разделитель - это единое пространство:
cut -d' ' -f4 infile | sort | uniq -c
Обратите внимание, что uniq
фильтрует соседние совпадающие строки, поэтому сначала нужно отсортировать
, например. с этим входом:
FAM193A
FAM155B
FAM169B
FAM171B
FAM132B
FAM193A
FAM132A
FAM132B
FAM155B
FAM169B
FAM171B
FAM171A
FAM193A
FAM132A
используя сортировку | uniq -c
производит:
2 FAM132A
2 FAM132B
2 FAM155B
2 FAM169B
1 FAM171A
2 FAM171B
3 FAM193A
, в то время как uniq -c | сортировка -k2
производит:
1 FAM132A
1 FAM132A
1 FAM132B
1 FAM132B
1 FAM155B
1 FAM155B
1 FAM169B
1 FAM169B
1 FAM171A
1 FAM171B
1 FAM171B
1 FAM193A
1 FAM193A
1 FAM193A
No he podido encontrar una solución sencilla. La forma más fácil que encontré para resolverlo fue usar una lista de "mantener" en lugar de una lista de "eliminar". Luego, podría agregar las últimas N copias de seguridad a la lista y las más nuevas del rango de cada semana durante M semanas. (En mi propio código, escrito hace algún tiempo, extendí a meses, trimestres y años. )Obviamente, habrá cierta superposición, pero como es una lista de "mantenimiento", eso no importa. Luego borras todo lo que no está en la lista -habiendo comprobado primero que la lista no está vacía.
#!/bin/bash
#
dirs=(
backup-2018-01-12
backup-2018-01-13
backup-2018-01-14
backup-2018-01-15
backup-2018-01-16
backup-2018-01-17
backup-2018-01-18
backup-2018-01-19
backup-2018-01-20
backup-2018-01-21
backup-2018-01-22
backup-2018-01-23
backup-2018-01-24
backup-2018-01-25
backup-2018-01-26
backup-2018-01-27
backup-2018-01-28
backup-2018-01-29
backup-2018-01-30
backup-2018-01-31
backup-2018-02-01
backup-2018-02-02
backup-2018-02-03
backup-2018-02-04
backup-2018-02-05
backup-2018-02-06
backup-2018-02-07
backup-2018-02-08
backup-2018-02-09
backup-2018-02-10
backup-2018-02-11
backup-2018-02-12
backup-2018-02-13
backup-2018-02-14
backup-2018-02-15
)
declare -A list
declare -A keep
####################################################################################
# Go
#
prefix="backup-"
today=$(date +%Y-%m-%d)
# Populate list from set of directories
#
for item in "${dirs[@]}"
do
list[$item]="$item"
done
# Build keep list from business criteria
#
for dayback in {0..6}
do
dateback=$(date --date "$today - $dayback day" +%Y-%m-%d)
keep[$prefix$dateback]=1
done
for weekback in {0..3}
do
dateback1=$(date --date "$today - $weekback week" +%Y-%m-%d)
dateback2=$(date --date "$today - $((weekback + 1)) week" +%Y-%m-%d)
# Look for newest in range
#
newest=
dateback="$dateback1"
while [[ $dateback != $dateback2 ]]
do
[[ -n ${list[$prefix$dateback]} ]] && newest=$dateback && break
dateback=$(date --date "$dateback - 1 day" +%Y-%m-%d)
done
[[ -n $newest ]] && keep[$prefix$newest]=1
done
# We now have a keep list, so delete anything not in that list
#
for item in "${list[@]}"
do
[[ -n ${keep[$item]} ]] && echo "KEEP $item" || echo "DELETE $item"
done
# All done
#
exit 0
Cuando esté satisfecho, cambie o extienda las declaraciones de eco hacia el final para realizar la eliminación real.
¿Qué pasa con esto?
for i in $(find. -maxdepth 1); do
if ! (( $((($(date +%s) - $(date +%s -r $i )) / 86400)) % 7)); then
echo $i # Print out the folder. Can be replaced with your action
fi
done
o como una sola línea:
for i in $(find. -maxdepth 1); do if ! (( $((($(date +%s) - $(date +%s -r $i )) / 86400)) % 7)); then echo "$i $i_weekly" ;fi; done
Esto debería imprimir todas las carpetas que deberían tener 7,14,21,28.... días de antigüedad. En lugar de "echo", haz un mv o lo que sea...
Вот пример скрипта для чередования резервных копий с сохранением последних 7 дней, 12 месяцев backup-*-*-01
и 10 летbackup-*-01-01
all=$(ls backup-*)
days=$(ls backup-* | tail -n 7)
monthes=$(ls backup-*-01 | tail -n 12)
years=$(ls backup-*-01-01 | tail -n 10)
keep=" $days $monthes $years "
for item in $all
do
if ! [[ "$keep" =~ "$item" ]]
then
echo "$item will be deleted"
# rm $item
fi
done