LINUX.ORG.RU

bash скрипт - специфичное удаление файлов

 , ,


0

2

Помогите разработать алгоритм для следующей задачи. Есть ряд бекапов - файлы с именем vzdump-qemu-100-2016_02_10-00_15_01.vma.gz В этом шаблоне изменяется цифра 100 (имя машины) и дата/время. Цифр этих много. Нужно: оставить только 2 файла на каждую машину. То есть надо 1) проход и выяснение имеющихся файлов машин, на выходе - массив машин (100,101,1001) 2) проход и удаление кроме последних X файлов по шаблону.

То есть оставить по паре файлов каждого бекапа. Как правильнее и проще?


Сортируешь по дате создания, потом итерациями проходишься по коду машины (с awk по столбцу или грепаешь, как хочешь), цепляешь две последних и перемещаешь, так для каждой. Остатки трёшь.

Bfgeshka ★★★★★
()

Питоном фигачь.

Создаем файлы.

touch vzdump-qemu-100-2016_02_10-00_15_01.vma.gz  vzdump-qemu-100-2016_02_10-00_15_02.vma.gz  vzdump-qemu-100-2016_02_10-00_15_03.vma.gz  vzdump-qemu-200-2016_02_10-00_15_01.vma.gz

Печатаем тех, кого надо удалить.

import glob
import itertools

files = glob.glob('*.vma.gz')

# vzdump-qemu-100-2016_02_10-00_15_03.vma.gz
files_with_ids = [(i, i.split('-')[2]) for i in files]

# vzdump-qemu-100-2016_02_10-00_15_03.vma.gz, 100
files_with_ids.sort(key=lambda x: x[1])


for k, g in itertools.groupby(files_with_ids, lambda x: x[1]):
    f = list(g);

    # 2 files only, nothing to delete
    if len(f) < 3: continue

    f.sort();

    # Drop the last 2 values
    first_files =f[:len(f) - 2]
    
    names_only = map(lambda x: x[0], first_files);
    
    for i in names_only:
        print(i)

vzdump-qemu-100-2016_02_10-00_15_01.vma.gz

Распечатанные файлы можешь сверить-удалить.

Только проверь внимательно: сортировка идет по имени, не по дате. Возможен адЪ и треш.

anonymous
()

Bfgeshka, AWK-то здесь нахрена?

whoim, если вы не знаете, как реализовать алгоритм, то и описывать его ни чему. Здесь не нужны два прохода, ибо список файлов мы, даже если не хотим, получаем сортированным.

#!/bin/bash

declare -A dumps_count
files=(vzdump-*)
for ((i = ${#files[@]} - 1; i >= 0; i--)); do
    f="${files[$i]}"
    IFS='-' read __ __ machine __ <<< "$f"
    (( ++dumps_count[$machine] > 2 )) \
        && rm -- "$f"
done
Zmicier ★★★★★
()

Может просто find заюзать?

GoNaX ★★★
()
Ответ на: комментарий от Zmicier

работает супер! и принцип понял, новое узнал. Спасибо еще раз!

whoim
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.