我目前正在使用 2 个脚本。 1 个按年份过滤文件的脚本。第二个脚本位于年份子文件夹内,按月份 # (01-12) 进行过滤。
有比我下面的更好的东西吗?
所有文件都位于 1 个目录中:
源:./tape_backup/sync1/*(140 万个文件) 目标:./tape_backup/<1990 - 2019>/<01-12>/(按年/月组织)
文件名语法:A1000_T195_R256393_D120498094600
_D = 不重要
D = 开始日期
1-2 = 月份
3-4 = 天(不重要)
5-6 = 年
7-* = 时间戳(不重要)
这就是为什么我做整个98
读起来像这样:
for f in ./sync1 do
(检查月份和年份,然后将其 mv 到月份和年份文件夹/)
完成
我使用 Cygwin 和服务器 2012 r2
#C:/cygwin/bin/bash
for filename in ./* ; do
if [[ $filename == *D??90 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/1990/
elif [[ $filename == *D??91 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/1991/
elif [[ $filename == *D??92 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/1992/
elif [[ $filename == *D??93 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/1993/
elif [[ $filename == *D??94 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/1994/
elif [[ $filename == *D??95 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/1995/
elif [[ $filename == *D??96 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/1996/
elif [[ $filename == *D??97 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/1997/
elif [[ $filename == *D??98 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/1998/
elif [[ $filename == *D??99 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/1999/
elif [[ $filename == *D??00 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2000/
elif [[ $filename == *D??01 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2001/
elif [[ $filename == *D??02 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2002/
elif [[ $filename == *D??03 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2003/
elif [[ $filename == *D??04 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2004/
elif [[ $filename == *D??05 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2005/
elif [[ $filename == *D??06 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2006/
elif [[ $filename == *D??07 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2007/
elif [[ $filename == *D??08 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2008/
elif [[ $filename == *D??09 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2009/
elif [[ $filename == *D??10 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2010/
elif [[ $filename == *D??11 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2011/
elif [[ $filename == *D??12 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2012/
elif [[ $filename == *D??13 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2013/
elif [[ $filename == *D??14 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2014/
elif [[ $filename == *D??15 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2015/
elif [[ $filename == *D??16 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2016/
elif [[ $filename == *D??17 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2017/
elif [[ $filename == *D??18 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2018/
elif [[ $filename == *D??19 ]] ; then
mv $filename /cygdrive/d/RAID5/RAID200/invoices/1/2019/
fi
done
答案1
执行 140 万次调用以mv
在不同驱动器之间移动内容将会很慢。尝试mv
少打几次电话。
假设??
您的模式中的 应该与世纪匹配:
for year in {1990..2019}; do
find . -maxdepth 1 -type f -name "*D$year" \
-exec mv -t "/cygdrive/d/RAID5/RAID200/invoices/1/$year/" {} +
done
这将循环所有相关年份。每年,它都会执行一个find
命令,一次批量移动尽可能多的与给定模式匹配的文件。
该代码假定您使用 GNU mv
(用于该-t
选项)和 GNU find
(或任何find
具有-maxdepth
)与 一起使用bash
。如果您的源目录不包含任何子目录,那么您可以-maxdepth 1
从命令中删除。
答案2
如果您要调用mv
140 万次,速度就会很慢 - 没有办法解决这个问题。但是您已经知道文件名的模式,所以为什么不批量处理它们,用一个调用多个文件mv
:
for yy in {1990..2019}
do
y=${yy#[0-9][0-9]} # remove first two digits of year
mv ./*D??"$y" "/cygdrive/d/RAID5/RAID200/invoices/1/$yy"
done
或者,如果遇到“超出参数长度”错误,请使用xargs
:
for yy in {1990..2019}
do
y=${yy#[0-9][0-9]}
printf "%s\0" ./*D??"$y" | # NUL-delimited filenames for xargs -0
xargs -0 -r mv -t "/cygdrive/d/RAID5/RAID200/invoices/1/$yy"
done
答案3
大家都知道 - 我使用了这个选项,作者:muru。我实际上尝试了上面发布的两个选项。
经过轻微修改...我用原来的 50 行代码每秒处理大约 3 个文件。现在我每秒大约做 30 - 50 次。
for yy in {1998..2018} do y=${yy#[0-9][0-9]} # 删除年份的前两位数字 mv -v ./sync1/_D???$y“/cygdrive/d/RAID5/RAID200/tape_backup/$yy”#mv -v ./sync1/_D???'$y'“/cygdrive/d/RAID5/RAID200/tape_backup/$yy”完成
:)