Новичок здесь: Я хочу синхронизировать изображения к папке, но хотеть, чтобы они были недавними. Вот почему я хочу, чтобы они были удалены, если они старше затем 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
Таким образом, мы хотим получить (регулярные) файлы, которые имеют 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 и выбора первые 20m+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)
Вот простой сценарий, чтобы сделать это:
#!/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
Протестировать его:
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 файлов вообще, они стары или нет.
Мой базовый подход совпадает с в ответе 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 --