현재 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
(월과 연도를 확인한 다음 월과 연도 폴더로 이동/)
완료
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
140만 번 전화를 걸면 mv
속도가 느려질 것입니다. 이를 피할 수 있는 방법이 없습니다. 그러나 파일 이름의 패턴을 이미 알고 있으므로 일괄 처리하여 여러 파일을 호출하는 것은 어떨까요 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" 완료됨
:)