Скрипты помогают найти команду через вывод времени в несколько файлов

Вот сценарий, который я написал, с которым мне нужна помощь. в скрипте я делаю поиск для любого файла, к которому не было доступа более 30 дней, 60, 90, 180, 270 и 365 дней.

Это работает просто отлично. однако для завершения 30-дневной части требуется несколько дней. это сканирование NAS. (миллионы и миллионы файлов), как вы видите, информация за 30 дней действительно содержит все данные, необходимые для остальных сценариев. часть скрипта 60, 90 и т. д. просто повторяет те же усилия, что и 30-дневная часть, за исключением продленного периода времени. в этом случае было бы сэкономлено несколько недель на повторное сканирование, если бы некоторые части 60, 90 180 и т. д. могли просто получить свои данные из 30-дневного вывода.

это где я прошу помощи. вывод аналогичен команде ls -l. и вы также можете видеть из результатов ниже, есть несколько лет в этом результате. скрипт прилагается и распечатывается ниже.

total 24
-rw-r--r-- 1 root bin 60 Apr 12 13:07 config_file
-rw-r--r-- 1 root bin 9 Apr 12 13:07 config_file.InProgress
-rw-r--r-- 1 root bin 0 Apr 12 13:07 config_file.sids
-rw-r--r-- 1 root bin 1284 Apr 19 10:41 rpt_file
-rw-r--r-- 1 16074 5003 20083 Apr 26 2002 /nas/quota/slot_2/CR_APP002/eb_ora_bin1/sun8/product/9.2s/oem_webstage/oracle/sysman/qtour/console/dat1_01.gif
-rw-r--r-- 1 16074 5003 20088 Apr 26 2002 /nas/quota/slot_2/CR_APP002/eb_ora_bin1/sun8/product/9.2s/oem_webstage/oracle/sysman/qtour/console/set1_04.gif
-rw-r--r-- 1 16074 5003 2008 Apr 26 2002 /nas/quota/slot_2/CR_APP002/eb_ora_bin1/sun8/product/9.2s/oem_webstage/oracle/sysman/qtour/oapps/get2_03.htm
-rw-r--r-- 1 16074 5003 20083 Apr 26 2002 /nas/quota/slot_2/CR_APP002/eb_ora_bin1/sun8/product/9.2s/oem_webstage/oracle/sysman/qtour/oapps/per1_01.gif

любая помощь приветствуется. Это дистрибутивы Linux, так что я уверен, что Perl там, если нужно..

#!/bin/ksh
############################################
# search shares for files                  #
# that have not been accessed              #
# for a certain time.                      #
# NOTE:                                    #
#    $IN = input search                    #
#    $OUT = output directory for text file #
##########################################################
# TESTS                                                  #
#     Numeric arguments can be specified as              #
#                                                        #
#     +n     for greater than n,                         #
#     -n     for less than n,                            #
#     n      for exactly n.                              #
#                                                        #
#     -atime n                                           #
#            File was last accessed n*24 hours ago.      #
#                                                        #
##########################################################


IN1=/nas/quota/slot_2/CR*
IN2=/nas/quota/slot_3/CR*
IN3=/nas/quota/slot_4/CR*
IN4=/nas/quota/slot_5/CR*
OUT=/nas/quota/slot_3/CR_PRJ144/steve
mkdir ${OUT}
for dir in ${IN1}; do find $dir -atime +30 -exec ls -l '{}' \; >>${OUT}/30days.txt; done
for dir in ${IN2}; do find $dir -atime +30 -exec ls -l '{}' \; >>${OUT}/30days.txt; done
for dir in ${IN3}; do find $dir -atime +30 -exec ls -l '{}' \; >>${OUT}/30days.txt; done
for dir in ${IN4}; do find $dir -atime +30 -exec ls -l '{}' \; >>${OUT}/30days.txt; done
for dir in ${IN1}; do find $dir -atime +60 -exec ls -l '{}' \; >>${OUT}/60days.txt; done
for dir in ${IN2}; do find $dir -atime +60 -exec ls -l '{}' \; >>${OUT}/60days.txt; done
for dir in ${IN3}; do find $dir -atime +60 -exec ls -l '{}' \; >>${OUT}/60days.txt; done
for dir in ${IN4}; do find $dir -atime +60 -exec ls -l '{}' \; >>${OUT}/60days.txt; done
for dir in ${IN1}; do find $dir -atime +90 -exec ls -l '{}' \; >>${OUT}/90days.txt; done
for dir in ${IN2}; do find $dir -atime +90 -exec ls -l '{}' \; >>${OUT}/90days.txt; done
for dir in ${IN3}; do find $dir -atime +90 -exec ls -l '{}' \; >>${OUT}/90days.txt; done
for dir in ${IN4}; do find $dir -atime +90 -exec ls -l '{}' \; >>${OUT}/90days.txt; done
for dir in ${IN1}; do find $dir -atime +180 -exec ls -l '{}' \; >>${OUT}/180days.txt; done
for dir in ${IN2}; do find $dir -atime +180 -exec ls -l '{}' \; >>${OUT}/180days.txt; done
for dir in ${IN3}; do find $dir -atime +180 -exec ls -l '{}' \; >>${OUT}/180days.txt; done
for dir in ${IN4}; do find $dir -atime +180 -exec ls -l '{}' \; >>${OUT}/180days.txt; done
for dir in ${IN1}; do find $dir -atime +270 -exec ls -l '{}' \; >>${OUT}/270days.txt; done
for dir in ${IN2}; do find $dir -atime +270 -exec ls -l '{}' \; >>${OUT}/270days.txt; done
for dir in ${IN3}; do find $dir -atime +270 -exec ls -l '{}' \; >>${OUT}/270days.txt; done
for dir in ${IN4}; do find $dir -atime +270 -exec ls -l '{}' \; >>${OUT}/270days.txt; done
for dir in ${IN1}; do find $dir -atime +365 -exec ls -l '{}' \; >>${OUT}/365days.txt; done
for dir in ${IN2}; do find $dir -atime +365 -exec ls -l '{}' \; >>${OUT}/365days.txt; done
for dir in ${IN3}; do find $dir -atime +365 -exec ls -l '{}' \; >>${OUT}/365days.txt; done

for dir in ${IN4}; do find $dir -atime +365 -exec ls -l '{}' \; >>${OUT}/365days.txt; done

3 ответа

Вам нужен фундаментальный редизайн. Вы должны выполнить команду find только один раз для всей системы и создать файл индекса, содержащий что-то вроде 'file: atime'. Вы можете сделать это с помощью -printf аргумент для поиска, чтобы напечатать atime с именем файла (см. man find). Затем вы можете выполнять свои операции на основе этого индекса. Причина в том, что самым большим штрафом будет указание каждого файла на диске, так что вы хотите сделать это только один раз. Это идея команд locate и updatedb в Linux. В основном вы хотите воссоздать те с добавлением atime.

Я также думаю, что цикл по ls - это дерьмо, вы, вероятно, хотите циклически проходить по индексу построчно с циклом while. Вам придется повторить истину тех времен в "х дней назад". Самый простой способ, вероятно, будет использовать эпоху. Таким образом, вы получите что-то вроде:

find ~/scrap -printf "%p:%A@%\n" > index;
while read -d':' name date; do
   if ...between dates using $date...; then
      do something to $name
   fi 
done < index

Если вы хотите вместо вышеупомянутого, у вас есть команда pipe к циклу while и вы перенаправляете в разные файлы на основе операторов if. Кроме того, имейте в виду: это плохой разделитель, если он может использоваться в имени файла.

Возможно, вы захотите сгенерировать индекс в SQL, если вы хотите стать более любопытным.

Есть несколько проблем со сценарием, которые заставляют его работать так медленно. Прежде всего, ваш цикл for не нужен в том виде, в котором он написан, поскольку каждая переменная имеет только одно значение, чтобы использовать его по своему усмотрению, вы бы изменили структуру на что-то вроде:

IN_PATH="
/nas/quota/slot_2/CR*
/nas/quota/slot_3/CR*
/nas/quota/slot_4/CR*
/nas/quota/slot_5/CR*
"
OUT=/nas/quota/slot_3/CR_PRJ144/steve
mkdir ${OUT}
for dir in ${IN_PATH}; do find $dir +atime 30
for dir in ${IN_PATH}; do find $dir +atime 60
for dir in ${IN_PATH}; do find $dir +atime 90

так далее..

Но это все еще заставляет цикл поиска по всей файловой системе NAS заявлять о каждом файле... МЕДЛЕННО! Так как мы проверяем время, мы должны проверить файлы, но почему бы не сделать это только один раз? Предполагая, что у вас есть Linux-машина со стандартным GNU, вы можете сделать что-то вроде этого:

find /nas/quota/ \(+atime 365 -fls /root/365.txt\), \(+atime 180 -fls /root/180.txt\), etc...

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

\(+atime 180 -a -atime 364 -fls /root/more_than_180_but_less_than_365.txt \)

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

Также попробуйте отформатировать свой пост. Это выглядит как нечитаемый блок текста прямо сейчас.

Другие вопросы по тегам