#bash #shell
#bash #оболочка
Вопрос:
Я пытаюсь идентифицировать и удалять файлы старше определенной постоянной даты в моем сценарии оболочки. Ниже приведен скрипт, который просто подсчитывает это. Я не могу использовать find или что-либо еще, что будет создавать аргументы, потому что в этом каталоге 1,5 млн файлов, и я получаю
-bash: /usr/bin/find: Argument list too long
ошибка. Итак, мои текущие сокращенные сценарии:
y=0;
cond=$(date -d 2020-10-15 %s)
for FILE in *tele*
do
if [ $FILE -ot $cond ]
then
y=$((y 1))
fi
done
echo $y
Он должен подсчитывать все файлы (текущая дата в будущем), но он возвращает 0. Я думаю, что я не использую правильные типы дат для сравнения.
Ответ №1:
Вот простой трюк для подсчета файлов:
find … -printf x | wc -c
В принципе, для каждого файла выведите байт «x», затем подсчитайте количество байтов.
Что касается причины сбоя вашего скрипта, краткий обзор для -ot
этого [ PATH1 -ot PATH2 ]
, который вы могли бы легко эмулировать следующим образом (непроверенный):
reference="$(mktemp)"
touch "--date=@${cond}" "$reference"
…
if [[ "$path" -ot "$reference" ]]
then
…
Сравнение времени выполнения:
$ cd "$(mktemp --directory)"
$ touch {1..100000}
$ time find . -mindepth 1 -printf x | wc -c
100000
real 0m0.072s
user 0m0.036s
sys 0m0.040s
$ time for FILE in *
do
if [ $FILE -ot 0 ]
then
y=$((y 1))
fi
done
real 0m0.438s
user 0m0.334s
sys 0m0.105s
find
Решение в ~ 6 раз быстрее для 100000 файлов.
Комментарии:
1. Потрясающе, большое спасибо, @l0b0, это работает. Мне никогда не приходило в голову, что оператор может работать только с файлами, я собирался попробовать то же самое, потому что я мог найти только примеры, в которых сравниваются два файла, но вы сэкономили мне много времени. Кстати, я не хотел считать файлы, это был просто способ протестировать мой скрипт. Кроме того, найдите разрывы в больших каталогах, отсюда и цикл for.
2.
find
не должен прерываться с каталогом любого размера; «Слишком длинный список аргументов» весьма вероятен только потому, что какой-то глобус расширился до байиллиона файловfind
еще до запуска.