Shell Script - Получить все файлы, измененные после <дата>

136

Я бы предпочел не делать этого в PHP, так что я надеюсь, что кто-то приличный в написании сценариев может помочь.

Мне нужен скрипт, который рекурсивно проходит через каталог и находит все файлы с датой последнего изменения, превышающей некоторую дату. Затем он заархивирует файл (ы) и сохранит информацию о пути.

Джонатан Леффлер
источник
14
Хорошее решение не делать это в PHP.
Креднс
1
Вы можете использовать любой из приличных языков сценариев оболочки, например, python, ruby, perl, не прибегая к php.
борозда
3
@garrow На самом деле это было бы довольно просто в PHP с использованием RecursiveDirctoryIterator, заключенного в FilterIterator.
Артефакт

Ответы:

136

так просто как:

find . -mtime -1 | xargs tar --no-recursion -czf myfile.tgz

где find . -mtime -1выберет все файлы в (рекурсивно) текущем каталоге, измененном днем ​​ранее. Вы можете использовать дроби, например:

find . -mtime -1.5 | xargs tar --no-recursion -czf myfile.tgz
Скрат
источник
4
Посмотрите ответ user104848 ниже о том, как бороться с пробелами в именах ваших файлов
Brian Henk
8
Преобразование произвольной временной метки в дробное относительное количество времени не кажется ни правильным, ни особенно удобным. Решение ниже , используя -newermtэто намного лучше.
Бобби Джек,
5
При попытке извлечь любые файлы с изменениями в структуре с помощью каталогов, сами каталоги помечаются как измененные, что приводит к архивированию всей папки. Добавить -type fтолько для выбора файлов. Это поддерживает структуру папок, но создает резервные копии только файлов с изменениями.
Брент
1
@BrianHenk user104848 изменили свое имя, я уверен, что вы имеете в виду этот ответ от (в настоящее время) Джейсона Лютера, хотя
icc97
4
Вопрос просит найти файлы к произвольной дате. Этот ответ заключается в том, как найти файлы за произвольное количество дней в прошлом. Я не думаю, что это должен быть принятый ответ без добавления шага для преобразования даты в дельту дня.
Марк
91

Если у вас есть GNU find, то есть множество соответствующих опций. Единственная загвоздка в том, что интерфейс к ним менее звездный:

  • -mmin n (время модификации в минутах)
  • -mtime n (время модификации в днях)
  • -newer file (время модификации новее, чем время модификации файла)
  • -daystart (отрегулируйте время начала от текущего времени до начала дня)
  • Плюс альтернативы времени доступа и времени «изменения» или «создания».

Трудная часть - это определение количества минут с определенного времени.

Стоит рассмотреть один вариант: использовать touchдля создания файла с необходимой отметкой времени модификации; затем используйте findс -newer.

touch -t 200901031231.43 /tmp/wotsit
find . -newer /tmp/wotsit -print
rm -f /tmp/wotsit

Это ищет файлы, более новые, чем 2009-01-03T12: 31: 43. Понятно, что в скрипте /tmp/wotsitбудет имя с PID или другим значением, чтобы сделать его уникальным; и было бы, trapчтобы гарантировать, что это будет удалено, даже если пользователь прерывает, и так далее, и так далее.

Джонатан Леффлер
источник
65
Вместо этого вы можете использовать, -newermt '2009-01-03T12:31:43'чтобы избежать необходимости создавать файл только для справки.
Майкл Миор
@MichaelMior: Интересно - функция «find» в MacOS X 10.7.2 поддерживает -newermt(документировано, -newerXYпоскольку существует несколько опций; в данном случае X = m, Y = t). Поиск GNU в (почти архаичных) системах Linux, которые я использую, не поддерживает опции, так что это относительно недавнее появление. Спасибо за внимание.
Джонатан Леффлер
Эта опция присутствует в GNU find 4.4.2, которую я использую в своей системе.
Майкл Миор
2
Также обратите внимание, что GNU find поддерживает также относительное время, т.е. -newermt '-2 weeks',
Cybolic
1
-newermt '2009-01-03T12:31:43'выглядит потрясающе, но, к сожалению, кажется, что все интерпретируется в неправильном часовом поясе: lists.gnu.org/archive/html/bug-findutils/2012-12/msg00009.html
antoine
35

Вы можете сделать это напрямую с помощью tar и даже лучше:

tar -N '2014-02-01 18:00:00' -jcvf archive.tar.bz2 files

Это дает tar команду сжимать файлы, выпущенные до 1 января 2014 года, 18:00:00.

linux_newbie
источник
9
Да ... Я использую Unix с 1984 года и никогда не знал этого. Всегда чему-то научиться.
Джон
Реализации tarэтого поставляются только с поддержкой OS X и FreeBSD, --newerчто является длинным вариантом для -NGNU tar.
nisetama
Это круто ... Я мог заставить его работать только с bzip, не используя -xcvf и расширение gz ... но я не эксперт.
Фил
17

Это будет работать для некоторого количества файлов. Вы хотите включить «-print0» и «xargs -0» на случай, если в любом из путей есть пробелы. Этот пример ищет файлы, измененные за последние 7 дней. Чтобы найти те, которые были изменены до последних 7 дней, используйте «+7».

find . -mtime -7 -print0 | xargs -0 tar -cjf /foo/archive.tar.bz2

Как предупреждает эта страница , xargs может вызвать многократное выполнение команды tar, если аргументов много, а флаг «-c» может вызвать проблемы. В этом случае вы хотели бы это:

find . -mtime -7 -print0 | xargs -0 tar -rf /foo/archive.tar

Вы не можете обновить заархивированный архив tar с помощью tar, поэтому вам придется выполнить bzip2 или gzip на втором шаге.

Джейсон Лютер
источник
1
Что касается второго пункта, вы можете использовать команду tar с поддержкой gzip, например, параметр -z в Gnu tar, чтобы также обновлять сжатые архивы.
Suncat2000,
Или добавьте опцию 'j', чтобы использовать bzip в последних версиях GNU
hd1
3
Как я уже говорил выше в ответе Джонатана, он будет захватывать папки, в которых есть изменения, в результате чего импортируются все их файлы. Добавить -type fтолько для выбора файлов. Это поддерживает структуру папок, но только создает резервные копии файлов с изменениями / добавленными недавно.
Брент
12

Это должно показать все файлы, измененные за последние 7 дней.

find . -type f -mtime -7 -print

Отправьте это в tar / zip, и вы должны быть хорошими.

Крис Доггетт
источник
4

Я бы просто сделал следующее, чтобы сделать резервную копию всех новых файлов от 7 дней назад

tar --newer $(date -d'7 days ago' +"%d-%b") -zcf thisweek.tgz .

обратите внимание, что вы также можете заменить «7 дней назад» на все, что вам нужно

Возможно : date -d'yesterday' +"%d-%b"

Или даже : date -d'first Sunday last month' +"%d-%b"

Мишель
источник
3

хорошо под linux попробуйте прочитать man-страницу команды find

man find

как то так должно

 find . -type f -mtime -7 -print -exec cat {} \; | tar cf - | gzip -9

и у тебя это есть

Luixv
источник
3

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

find . -mtime -x

Тогда вам просто нужно архивировать и архивировать файлы в результирующем списке, например:

tar czvf mytarfile.tgz `find . -mtime -30`

для всех файлов, измененных за последний месяц.

mouviciel
источник
3
«-mtime x» соответствует файлам, измененным ровно «x» дней назад, используйте «-mtime -x» для сопоставления файлов, измененных меньше, чем «x» дней назад.
Ланс Ричардсон
2

Этот скрипт найдет файлы с датой изменения за две минуты до и после указанной даты (и вы можете изменить значения в условиях согласно вашему требованию)

PATH_SRC="/home/celvas/Documents/Imp_Task/"
PATH_DST="/home/celvas/Downloads/zeeshan/"

cd $PATH_SRC
TODAY=$(date  -d "$(date +%F)" +%s)
TODAY_TIME=$(date -d "$(date +%T)" +%s)


for f in `ls`;
do
#       echo "File -> $f"
        MOD_DATE=$(stat -c %y "$f")
        MOD_DATE=${MOD_DATE% *}
#       echo MOD_DATE: $MOD_DATE
        MOD_DATE1=$(date -d "$MOD_DATE" +%s)
#       echo MOD_DATE: $MOD_DATE

DIFF_IN_DATE=$[ $MOD_DATE1 - $TODAY ]
DIFF_IN_DATE1=$[ $MOD_DATE1 - $TODAY_TIME ]
#echo DIFF: $DIFF_IN_DATE
#echo DIFF1: $DIFF_IN_DATE1
if [[ ($DIFF_IN_DATE -ge -120) && ($DIFF_IN_DATE1 -le 120) && (DIFF_IN_DATE1 -ge -120) ]]
then
echo File lies in Next Hour = $f
echo MOD_DATE: $MOD_DATE

#mv $PATH_SRC/$f  $PATH_DST/$f
fi
done

Например , вы хотите , чтобы файлы , имеющие дату изменения до того , как данная дата только вы можете изменить , 120чтобы 0в $DIFF_IN_DATEпараметре отбрасывая условия$DIFF_IN_DATE1 параметра.

Аналогично, если вы хотите, чтобы файлы имели дату изменения за 1 час до и после заданной даты, просто замените их 120на 3600in if CONDITION.

Зеешан Али
источник