200개 이상의 하위 디렉터리 "영화 이름(연도)"가 포함된 "New Movies" 디렉터리가 있습니다. 하위 디렉토리 "영화 이름(연도)"에는 비디오 파일(avi/mkv) 및 여러 관련 jpg/xml 파일이 포함되어 있습니다.
최소 180일이 지난 비디오 파일이 포함된 모든 디렉터리를 다른 디렉터리로 이동해야 합니다.
예를 들어:
새 영화/영화 A(연도)에는 movie.mkv,folder.jpg 및 movie.xml이 포함됩니다. 다른 곳에서 같은 이름의 하위 디렉터리로 이동하고 모든 파일이 존재하고 그대로 유지되도록 하려고 합니다.
이 사이트의 다른 곳을 살펴본 후 다음을 시도했습니다.
cd "/mnt/user/New Movies/"
find -type f \( -name "*.avi" -or -name ".*mkv" \) -mtime +180 -exec sh -c 'mv "${0%/*}" /mnt/user/Movies' {} \;
이 명령은 첫 번째 하위 디렉터리와 모든 파일을 새 디렉터리로 성공적으로 이동했지만 그 이후의 모든 작업은 오류를 반환합니다.
find: './Movie B (year)': No such file or directory
find: './Movie C (year)': No such file or directory
이동 여부에 관계없이 "새 영화" 아래에 포함된 모든 디렉토리를 탐색합니다.
답변1
-exec mv
현재 확인 중인 디렉터리를 확인 하지 마세요 find
. find
이렇게 하면 혼란스러울 것 같습니다.
해결 방법: 먼저 디렉터리를 찾은 다음 이동합니다.
cd "/mnt/user/New Movies/"
find -type f \( -name "*.avi" -or -name ".*mkv" \) -mtime +180 \
-printf "%h\0" | xargs -0 mv -t /mnt/user/Movies
설명하다:
-printf
형식 문자열에 따라 일치 항목을 인쇄합니다.%h
일치하는 경로 부분을 인쇄합니다. 이는"${0%/*}"
귀하의 명령에 해당합니다.\0
항목을 구분하려면 null 문자를 사용하세요. 이는 파일 이름에 개행 문자가 포함되는 것을 방지하기 위한 것입니다.xargs
파이프라인에서 입력을 수집한 다음 추가된 입력 매개변수를 사용하여 실행합니다.-0
입력이 개행 구분이 아닌 널 구분으로 예상되도록 xargs에 지시합니다.mv -t <target>
mv
호출 시 모든 소스 매개변수가 끝에 추가되도록 허용합니다 .
아직 완전히 안전하지는 않습니다. 파이프 버퍼와 결합된 일부 이상한 스케줄러 타이밍으로 mv
인해 디렉터리 밖으로 이동하기 전에 여전히 실행이 발생할 수 있습니다 . find
이를 방지하려면 다음을 수행할 수 있습니다.
cd "/mnt/user/New Movies/"
find -type f \( -name "*.avi" -or -name ".*mkv" \) -mtime +180 \
-printf "%h\0" > dirstomove
xargs -0 mv -t /mnt/user/Movies < dirstomove
배경 참고 사항:
귀하의 상황은 다음과 같다고 생각합니다 find
.
find
디렉토리를 탐색합니다/mnt/user/New Movies/
. 거기에서 캐시에 사용 가능한 디렉터리를 기록합니다.find
시스템 호출을 사용하여 하위 디렉터리 중 하나로 이동합니다chdir(subdirname)
.find
필터를 통과한 동영상 파일을 찾아보세요.find
mv
주어진 매개변수를 사용하여 실행됩니다.mv
디렉토리를 로 이동합니다/mnt/user/Movies
.find
시스템 호출을 사용하여 상위 디렉토리로 돌아가면chdir(..)
이제 호출은/mnt/user/Movies
대신 다음 을 가리킵니다./mnt/user/New Movies/
find
앞서 적어둔 디렉토리를 찾을 수 없고 많은 오류가 발생하기 때문에 매우 혼란스럽습니다.
이 가정은 다음 질문에 대한 답변을 기반으로 합니다.find -exec mv가 첫 번째 실행 후 중지됨. find
이 경우 왜 작동이 중지되고 귀하의 경우 오류가 발생하는지 모르겠습니다 . 다른 버전이 find
설명일 수 있습니다.
답변2
설정IFSIFS=$(echo -en "\n\b");
쉘이 공백 대신 개행을 기준으로 항목을 구분하도록 하는 환경 변수입니다 .
게다가 -exec sh -c 'mv "${0%/*}" /mnt/user/Movies' {} \;
이상해요. 내가 올바르게 기억한다면 다음과 같이 간단해진다.-exec mv {} /mnt/user/Movies \;