这是我编写的一个脚本,需要帮助。在脚本中,我查找任何超过 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
答案1
您需要进行根本性的重新设计。您应该在整个系统中只运行一次 find 命令,然后创建一个包含类似“file:atime”内容的索引文件。您可以使用-printf
find 的参数打印文件名的 atime(请参阅man find
)。然后,您可以根据该索引执行操作。这样做的原因是最大的惩罚是声明磁盘上的每个文件,因此您只想执行一次。这是 Linux 上locate 和updatedb 命令背后的想法。基本上,您希望通过添加atime 来重新创建它们。
我也认为循环遍历 ls 很糟糕,您可能希望使用 while 循环逐行循环遍历索引。您将不得不将这些时间复制到“x 天前”。最简单的方法可能是使用纪元。因此,您最终会得到类似以下内容的结果:
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
如果您不想使用上述方法,可以将 find 命令导入 while 循环,并根据 if 语句重定向到不同的文件。另外,请记住,如果 : 可能用在文件名中,则它是一个不好的分隔符。
如果您想要更加精美,您可能需要在 SQL 中生成索引。
答案2
脚本中有几个问题导致其运行速度如此缓慢。首先,您的 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
ETC..
但这仍然会让 find 循环遍历整个 NAS 文件系统,并声明每个文件……太慢了!由于我们要检查 atime,因此必须声明文件,但为什么不只做一次呢?假设您有一台装有标准 GNU find 的 Linux 机器,您应该可以做这样的事情:
find /nas/quota/ \(+atime 365 -fls /root/365.txt\), \(+atime 180 -fls /root/180.txt\), etc...
现在我根据记忆来做这件事,所以可能需要进行一些调整才能完全正常工作,在 Web 根目录或您的主目录中对其进行测试,这些目录运行速度很快,有助于排除故障。 Find 将接受多个表达式,如果您阅读手册页的优先级部分,您可以让它做一些漂亮的事情。根据您想要用这些信息做什么,您还可以为 atime 检查添加限制,例如:
\(+atime 180 -a -atime 364 -fls /root/more_than_180_but_less_than_365.txt \)
答案3
如果需要天只是为了完成搜索的一部分,这意味着你的脚本正在不应该循环的地方循环。最重要的是你一遍又一遍地进行递归查找......
另外,请尝试格式化您的帖子。它现在看起来像是不可读的文本块。