Я имею каталог, содержащий большое количество файлов для итерации, и хотел бы эффективный способ найти субботу до времени файла последнего изменения.
Вот два примера. Первым является просто простой файл, который был отредактирован на
$ date -r file_1
Wed Jun 21 08:26:35 CDT 2017
$ date -d "$(date -r file_1 '+%F') - $(date -r file_1 '+%u') days - 1 days"
Sat Jun 17 00:00:00 CDT 2017
Если это было изменено в субботу, я хочу в предыдущую субботу.
$ date -r file_2
Sat Jun 17 00:00:00 CDT 2017
$ date -d "$(date -r file_2 '+%F') - $(date -r file_2 '+%u') days - 1 days"
Sat Jun 10 00:00:00 CDT 2017
Как Вы видите, у меня есть метод выполнения этого, но процесс в вычислительном отношении очень длинен. Это вынуждает дату сделать естественный английский парсинг и когда Вы делаете это сотни или тысячи времен, это очень медленно.
Приблизительно в 100 раз более быстрый метод, с помощью stat
получить даты, затем date -f -
дважды сделать математику и форматирование, с /usr/bin/*
(4 852 файла) как пример:
stat -c %y /usr/bin/* | date -f - "+%F - %u days - 1 days" | date -f -
Вывод является 4 852 строками различных дат, все из которых являются предыдущими субботами.
Медленнее: Объединение двух date
подоболочки работают приблизительно в на 33% меньшее количество времени:
date -r /bin/bash "+%F" # print this only for reference
date -d "$(date -r /bin/bash "+%F - %u days - 1 days")"
Вывод:
2017-05-16
Sat May 13 00:00:00 EDT 2017
Сравнительный тест для обоих, (2-й метод в a for
цикл):
$ time -p stat -c %y /usr/bin/* | date -f - "+%F - %u days - 1 days" | \
date -f - > /dev/null
real 0.19
user 0.14
sys 0.19
$ time -p for f in /usr/bin/* ; do \
date -d "$(date -r "$f" "+%F - %u days - 1 days")" ; done > /dev/null
real 27.31
user 8.11
sys 14.93