我正在编写一个批处理程序,以删除文件名中具有条件的目录中的所有文件。
目录中有大量文本文件(〜数十万个文件),文件名固定为“ abc” +日期
abc_20180820.txt
abc_20180821.txt
abc_20180822.txt
abc_20180823.txt
abc_20180824.txt
程序尝试grep所有文件,将日期与固定日期进行比较,如果文件名的日期<固定日期,则将其删除。 但是问题是处理这么大的文件花了很长时间(删除30万个文件大约需要1个小时)。
我的问题:运行ls命令时是否可以比较日期?不在列表中获取所有文件,然后比较删除,但仅列出已满足条件的文件,然后删除。我认为这样会更好。
我的代码是
TARGET_DATE = "5-12"
DEL_DATE = "20180823"
ls -t | grep "[0-9]\{8\}".txt\$ > ${LIST}
for EACH_FILE in `cat ${LIST}` ;
do
DATE=`echo ${EACH_FILE} | cut -c${TARGET_DATE }`
COMPARE=`expr "${DATE}" \< "${DEL_DATE}"`
if [ $COMPARE -eq 1 ] ;
then
rm -f ${EACH_FILE}
fi
done
发现了一些类似的问题,但我不知道如何解决 List file using ls with a condition and process/grep files that only whitespaces
答案 0 :(得分:0)
您可以执行以下操作:
rm 201[0-7]*.txt # remove all files from 2010-2017
rm 20180[1-4]*.txt # remove all files from Jan-Apr 2018
# And so on
...
删除大量文件。这样您的代码就会运行得更快。
答案 1 :(得分:0)
是的,如果一个文件夹中有太多文件,则需要花费很多时间。 将这么多文件保存在一个文件夹中是个坏主意。即使是简单的ls或find也将杀死存储。而且,如果您有一些脚本可以遍历文件,则可以肯定会杀死存储。 因此,等待一小时将其清洁后。花一些时间,使文件夹结构更好。最好根据年/月/日...可能是小时对文件进行排序 例如
somefolder/2018/08/24/...files here
然后,您可以轻松删除,移动压缩文件……整月或整年。
答案 2 :(得分:0)
这是一个重构,它摆脱了讨厌的ls
。在大目录上循环仍然会有些慢。
# Use lowercase for private variables
# to avoid clobbering a reserved system variable
# You can't have spaces around the equals sign
del_date="20180823"
# No need for ls here
# No need for a temporary file
for filename in *[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].txt
do
# Avoid external process; use the shell's parameter substitution
date=${filename%.txt}
# This could fail if the file name contains literal shell metacharacters!
date=${date#${date%?????????}}
# Avoid expr
if [ "$date" -lt "$del_date" ]; then
# Just print the file name, null-terminated for xargs
printf '%s\0' "$filename"
fi
done |
# For efficiency, do batch delete
xargs -r0 rm
通配符扩展仍将花费相当长的时间,因为shell将对文件名列表进行排序。更好的解决方案可能是将其重构为find
命令,从而避免排序。
find . -maxdepth 1 -type f \( \
-name '*1[89][0-9][0-9][0-9][0-9][0-9][0-9].txt' \
-o -name '*201[0-7][0-9][0-9][0-9][0-9].txt' \
-o -name '*20180[1-7][0-9][0-9].txt ' \
-o -name '*201808[01][0-9].txt' \
-o -name '*2018082[0-2].txt' \
\) -delete
答案 3 :(得分:0)
我在此线程中找到了解决方案。 https://unix.stackexchange.com/questions/199554/get-files-with-a-name-containing-a-date-value-less-than-or-equal-to-a-given-inpu
awk
命令是如此强大,只花我一分钟即可处理数十万个文件(与循环相比,是1/10)。
ls | awk -v date="$DEL_DATE" '$0 <= date' | xargs rm -vrf
我什至可以用该命令以我所见过的最快答案来计数,复制和移动。
COUNT="$(ls | awk -v date="${DEL_DATE}" '$0 <= target' | xargs rm -vrf | wc -l)"