3

Я пытаюсь написать что-то похожее на удаление файлов старше 1 месяца, но оставляю файлы, созданные в 1-й день месяца.
Разница в том, что мне нужен один файл в месяц.

Я использую сценарий со своей средой сборки, которая не выполняется ежедневно из-за опроса scm.

Я думаю, что единственный способ добиться этого - использовать find, чтобы получить все "старые" файлы и выполнить некоторые проверки.
Сначала я удалил бы все файлы из списка, который был сохранен как файл месяца. Затем я удаляю один файл как файл месяца из списка, а после него я удаляю все файлы из списка.

Я пропустил функциональность найти или подобное?

1 ответ1

4

Резюме: наиболее полное решение - последнее, выберите то, которое подходит вам лучше всего, в зависимости от того, что именно вы хотите сделать.


На самом деле, если вам нужно хранить один файл в месяц, вы можете просто переименовать все файлы в month . Это будет перезаписывать все, кроме одного файла в месяц. Вы не дали никакой информации о том, какой тип файла или где эти файлы. Я предполагаю, что все файлы находятся в одном каталоге и нет подкаталогов. Если это не так, пожалуйста, обновите свой вопрос, указав более подробную информацию, и я обновлю свой ответ.

for file in *; do 
  month=$(date -d `stat -c %y $file | cut -f 1 -d ' ' ` +%B);
  mv $file $month;
done 

Сценарий выше оставит вам файлы с именами January , February и т . Д. Если вам нужно сохранить исходные имена файлов, вы можете попробовать это:

for file in *; do 
 month=$(date -d `stat -c %y $file | cut -f 1 -d ' ' ` +%B); 
 rm *.$month; 
 mv $file $file.$month; 
done

В результате у вас останутся файлы с именем <FILENAME>.<MONTH> , например, foo.January


Оба решения выше очень просты. Более общее решение, которое также будет работать с файлами в подкаталогах и пропускать файлы, которым меньше месяца, это:

find . -type f -mtime +29 | while IFS= read -r file; do 
 month=$(date -d `stat -c %y "$file" | cut -f 1 -d ' ' ` +%B); 
 find . -type f -name "*$month" -delete
 mv "$file" "$file.$month"; 
done

ЗАМЕТКИ:

  • Приведенное выше решение будет искать файлы, возраст которых не менее месяца, в текущем каталоге и во всех подкаталогах, и будет хранить только один файл в месяц. Это означает, что если у вас есть два файла, которые были последний раз изменены в январе, один из которых - ./foo а другой - baz/bar , то будет сохранен только один ./foo.January или baz/bar.January

  • Это предполагает, что у вас нет файлов с прошлого года, которые можно назвать foo.January Если вы это сделаете, они будут удалены.


Наконец, немного более сложный, который позволит вам сохранить имена файлов без изменений и избежать проблем, упомянутых выше:

tmp=`mktemp -u XXXX`;
find . -type f -mtime +29 | while IFS= read -r file; do 
  date=$(date -d `stat -c %y "$file" | cut -f 1 -d ' ' ` +%B%Y);
  foo=$tmp"_"$date; 
  find . -type f -name "*$foo" -delete
  mv "$file" "$file.$foo"; 
done
find . -type f -name "*$tmp*" | while IFS= read -r file; do 
  mv "$file" "${file%.*}";
done 

ОБЪЯСНЕНИЕ:

Этот скрипт использует mktemp -u XXXX (например , Xy12 , чтобы сгенерировать случайную строку , которая затем объединяется с датой (например , January2008 файла. Все файлы возрастом не менее месяца (> 29 дней, извините за февраль) затем переименовываются в filename.Xy12_January2008 . Второй цикл находит все файлы, имя которых содержит случайную строку (Xy12), и удаляет их расширение, поэтому filename.Xy12_January2008 снова становится filename .

Окончательный результат - один файл из каждого месяца каждого года без изменения исходного имени файла. Сценарий может работать с именами файлов с пробелами и будет искать файлы в текущем каталоге и во всех подкаталогах.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .