Удалите файлы в каталоге, более старом, чем 7 дней, но всегда оставляйте по крайней мере 20 файлов неповрежденными

Новичок здесь: Я хочу синхронизировать изображения к папке, но хотеть, чтобы они были недавними. Вот почему я хочу, чтобы они были удалены, если они старше затем 7 дней.

Текущий код для него:

find ./recentpicturesdirectory -mtime -7 -type f -delete 

Теперь мне нужно исключение, потому что должен всегда быть минимум 20 изображений в папке.

Я провел некоторое исследование, но не могу понять это. Возможно, используйте что-то еще затем команда находки?

Сначала печальная попытка (сказал Вам, я - новичок),

SIZE=find recentpictesfolder -type f | wc -l

find ./recentpicturesdirectory -mtime -7 -type f \(-iname ".*" ! **if files part of -> .. i dont know ...**$SIZE ) -delete 
0
задан 7 July 2017 в 11:57

3 ответа

Таким образом, мы хотим получить (регулярные) файлы, которые имеют mtime больше чем 7 дней назад И не в 20 новейших файлах.

Один способ сделать, который должен создать список файлов наряду с их временем изменения и флагом, указывающим, является ли файл mtime +7 или нет. Мы можем затем отсортировать список по mtime, и возьмите все кроме 20 большая часть recent1. Наконец, выполните итерации по получающемуся списку и удалите только тех, которые встречают порог возраста:

find ./recentpicturesdirectory -type f \( -mtime +7 -printf 'Y\t' -o -printf 'N\t' \) -printf '%A@\t%p\0' |
  sort -zk2,2 | head -zn -20 | while read -r -d '' flag _ file; do \
    case "$flag" in 
      'Y') echo rm "$file" 
           ;; 
        *) echo "skipping $file (too new)"
           ;; 
    esac
  done

При помощи \0 завершение и добавление -z отметьте к sort и head (или tail) команды, мы можем обработать любые легальные имена файлов, не дросселируя на пробеле.

echo добавляется для тестирования; удалите его, после того как Вы уверены, что желаемые файлы выбраны для удаления.

1, Если мы сортируем в порядке возрастания mtime (т.е. старый к новому), мы можем использовать head -n -20 выбрать всех кроме последних 20; альтернативно мы могли отсортировать в порядке убывания mtime (в новинку для старого) и использование tail -n +21


Если Вы имеете zsh, затем можно сделать все это со спецификаторами шарика, я думаю:

rm ./recentpicturesdirectory/**/*(.^om[1,20]^m+7)

где

  • **/* соответствия рекурсивно (эквивалентный из удара globstar)
  • (.) соответствуйте регулярным файлам только
  • om[1,20] списки заканчиваются в порядке возрастания mtime и выбора первые 20
  • m+7 соответствуйте только файлам mtime > 7 дней
  • ^ инвертируйте все, что следует

таким образом, логика

regular files NOT (in 20 most recent by mtime OR NOT mtime +7 days)

который (приложением правил de Morgan) эквивалентен

regular files (NOT in 20 most recent by mtime) AND (mtime +7 days)

Сделайте пробный прогон сначала хотя, например.

print -rl ./recentpicturesdirectory/**/*(.^om[1,20]^m+7)
1
ответ дан 2 November 2019 в 23:48

Вот простой сценарий, чтобы сделать это:

#!/bin/bash

IMGSPATH="/path/to/somewhere"

# count of all files within your directory
count=$(find $IMGSPATH -type f | wc -l)

# remove the ones older than of 7 days
while [ "$count" -gt "20" ]
do 
 find $IMGSPATH -type f -mtime +7 -print -delete -quit
 count=$((--count))
done
  1. Сначала мы считаем все файлы в рамках Вашего желаемого каталога.
  2. В то время как количество файлов в рамках того каталога больше, чем "20", затем сделайте:
    • Найдите первый файл более старым, чем "7" дни.
    • Удалите его
    • Уменьшите количество доступных файлов
    • Сделайте "#2" снова...

Протестировать его:

mkdir /tmp/lab
cd /lab
touch {1..40}
touch -d "10 days ago" {1..20}

Сохраните сценарий и выполните его для /tmp/lab теперь файлы 1 - 20 должны быть удалены, выполнены:

touch -d "10 days ago" {21..35}

запустите скрипт снова, ничто не получит удаленную причину, у Вас нет больше, чем 20 файлов вообще, они стары или нет.

0
ответ дан 2 November 2019 в 23:48

Мой базовый подход совпадает с в ответе steeldriver, но я собираюсь сохранить его немного более простым. Следующие команды распечатают список файлов в recentpicturesdirectory исключение retain_count (20) самый молодой и все моложе, чем retain_younger_days дни (7).

find recentpicturesdirectory -type f -printf '%T@ %p\0' |
sort --zero-terminated --reverse --numeric-sort --field-separator=' ' --key 1,1 |
gawk -F ' ' -v RS='\0' -v ORS='\0' -v retain_count=20 -v retain_younger_days=7 \
  'BEGIN{ maxage = systime() - retain_younger_days * 24 * 3600; }
  (NR > retain_count) && (int($1) < maxage) { print(substr($0, length($1) + 2)); }'

Так как вывод завершается пустым указателем, можно хотеть передать его по каналу через tr '\0' '\n' отобразить его человекочитаемо.

Объяснение

  • find recentpicturesdirectory -type f -printf '%T@ %p\0'

    Выберите (вложенные) записи recentpicturesdirectory которые являются регулярными файлами (-type -f) и распечатайте их время последнего изменения и соедините каналом завершенный нулевым символом (-printf '%T@ %p\0').

  • sort --zero-terminated --reverse --numeric-sort --field-separator=' ' --key 1,1

    Записи вида завершаются нулевым символом (-z/--zero-terminated) на основе первого поля (-k/--key 1,1) с разделителем полей пробела (-t/--field-separator=' ') интерпретируемый как десятичные числа (-n/--numeric-sort) в порядке убывания (-r/--reverse).

  • gawk -F ' ' -v RS='\0' -v ORS='\0' -v retain_count=20 -v retain_younger_days=7

    Запустите программу AWK GNU с разделителем полей пробела (-F ' '), входной и выходной разделитель записей нулевого символа (-v RS='\0' -v ORS='\0') и переменные retain_count и retain_younger_days набор к 20 и 7 соответственно.

  • BEGIN{ maxage = systime() - retain_younger_days * 24 * 3600; }

    При начинании набора программы maxage к текущему системному времени в секундах минус значение retain_younger_days преобразованный от дней до секунд.

  • (NR > retain_count) && (int($1) < maxage)

    Выберите рекордные числа выше retain_count и значение в первом столбце ниже maxage.

  • print(substr($0, length($1) + 2))

    Распечатайте текущую запись, опускающую первое поле и последующего разделителя полей, т.е. путь после времени изменения.

Как удалить печатные файлы

Если Вы подтвердили, что хотите удалить перечисленные файлы, можно передать список по каналу к:

xargs -r0 -- rm --
0
ответ дан 2 November 2019 в 23:48

Другие вопросы по тегам:

Похожие вопросы: