Примечание: Хотя есть ответ от jeff-schaller, он зависит от zsh
; поэтому я хотел бы получить ответ, основанный на Bash
.
Мне нравится создавать скрипт Bash для условного удаления старых файлов из резервной копии.
Для создания двух отдельных резервных копий файлов необходимо выполнить два условия:
1. Сохраните последнюю копию Edge_Profile_*.tgz
и удалите остальную часть.Edge_Profile_*.tgz
только если они старше 5 дней.
2. Сохраните последнюю копию Firefox_Profile_*.tgz
и удалите остальную часть.Firefox_Profile_*.tgz
.неважно, сколько им лет.
Вот как я изменил этот ответ AskUbuntu:https://askubuntu.com/a/933098/928088
Сценарий:
#!/bin/bash
LOG_FILE="/home/admn/Cleanup.log"
TEMP_LOG="/tmp/Temp_Cleanup.log"
mv $LOG_FILE $TEMP_LOG
{
cd /home/admn/Downloads/Test;
echo "Cleanup log:" `date`
find /home/admn/Downloads/Test/Edge_Profile_*.tgz -type f \( -mtime +5 -printf 'Y\t' -o -printf 'N\t' \) -printf '%A@\t%p\0' |
sort -zk2,2 | head -zn -1 | while read -r -d '' flag _ file; do \
case "$flag" in
'Y') echo rm "$file"
;;
*) echo "skipping $file (too new)"
;;
esac;
done
echo
find /home/admn/Downloads/Test/Firefox_Profile_*.tgz -type f \( -printf 'Y\t' -o -printf 'N\t' \) -printf '%A@\t%p\0' |
sort -zk2,2 | head -zn -1 | while read -r -d '' flag _ file; do \
case "$flag" in
'Y') echo rm "$file"
;;
*) echo "skipping $file (too new)"
;;
esac
done
} &>> $LOG_FILE
cat $TEMP_LOG >>$LOG_FILE
exit;
Вывод в файле журнала echo
:
/usr/local/scripts/cleanup.sh
rm /home/admn/Downloads/Test/Edge_Profile_Jul_06_2021_00-35.tgz
rm /home/admn/Downloads/Test/Edge_Profile_Jul_07_2021_00-35.tgz
....
skipping /home/admn/Downloads/Test/Edge_Profile_Jul_12_2021_00-35.tgz (too new)
skipping /home/admn/Downloads/Test/Edge_Profile_Jul_13_2021_00-35.tgz (too new)
....
rm /home/admn/Downloads/Test/Firefox_Profile_Jul_01_2021_00-35.tgz
rm /home/admn/Downloads/Test/Firefox_Profile_Jul_02_2021_00-35.tgz
....
Вывод в файле журнала во время фактического выполнения скрипта, без echo
:
/home/admn/Downloads/cleanup.sh: line 24: skipping /home/admn/Downloads/Test/Edge_Profile_Jul_12_2021_00-35.tgz (too new): No such file or directory
/home/admn/Downloads/cleanup.sh: line 24: skipping /home/admn/Downloads/Test/Edge_Profile_Jul_13_2021_00-35.tgz (too new): No such file or directory
....
Всего файлов в каталоге: 20 файлов
1, Edge_Profile_*.tgz: С 06 июля по 17 июля: 12 файлов
2, Firefox_Profile_*.tgz: С 01 июля по 08 июля: 8 файлов
Проблемы:
(1) ЯдуматьСкрипт в целом работает, но я не уверен, так как большую его часть я изменил, не зная, что происходит.
(2) Вывод в файл журнала:
Я бы предпочел точно такой же вывод в файле журнала, который я получаю с помощью echo
, за исключением только имен файлов (не с полным путем), например:
rm Edge_Profile_Jul_11_2021_00-35.tgz
skipping Edge_Profile_Jul_12_2021_00-35.tgz (too new)
ОС: Ubuntu MATE 21.04
Большое спасибо.
решение1
Манипулировать файлами на основе времени их модификации гораздо проще в оболочке, которая позволяет вам получать к ним прямой доступ. zsh — одна из таких оболочек. Просто sudo apt install zsh
установить ее. Поскольку ваши файлы, по-видимому, находятся в одном каталоге, этот ответ нерекурсивный. Сначала продемонстрируем более простой случай:
Чтобы сохранить последнюю копию Firefox_Profile_*.tgz и удалить все остальные, независимо от их возраста:
echo would rm -v -- Firefox_Profile_*.tgz(.om[2,-1])
Удалить
echo would
часть, если она выглядит правильно. Это используетквалификатор glob (wildcard)внутри скобок нужно сделать три вещи:- выберите только простые файлы (не каталоги, не сокеты и т.п.) с помощью
.
- упорядочить (сортировать) файлы по времени их изменения, от новых к старым, с
om
- выберите фрагмент результирующего списка, начиная со второго элемента и до конца, пропуская первый (самый новый) файл, с
[2,-1]
Если соответствующих файлов нет, zsh остановится и выдаст сообщение «zsh: совпадений не найдено» и не выполнит файл
rm
.- выберите только простые файлы (не каталоги, не сокеты и т.п.) с помощью
Чтобы сохранить последнюю копию Edge_Profile_*.tgz и удалить остальные, только если они старше 5 дней, сначала мы берем последнюю:
newest=(Edge_Profile_*.tgz(.om[1]))
... а затем мы получаем те, которые старше пяти дней:
older=(Edge_Profile_*.tgz(.m+5))
Новая часть здесь — это модификатор
+5
onm
. Он выбирает файлы старше 5 дней. После этого мы убеждаемся, что самый новый не находится в списке для удаления:remove=("${(@)older:|newest}")
Новая часть здесь — это символ вычитания массива.
:|
; он задокументирован вРаздел «Расширение параметров» руководства zsh. Он выбирает элементы "older", которых нет в "newest". Наконец, мы удаляем этот список файлов:echo would rm -v -- "${remove[@]}"