나는 최선을 다했지만 스크립팅에 대해 아는 바가 거의 없습니다. 스크립트는 내가 지정한 디렉터리와 모든 하위 디렉터리를 검색하고, 비디오 리소스를 검색하고, 손상되거나 잘못된 파일을 생성된 00errors 폴더로 이동해야 합니다.
스캔할 모든 하위 디렉터리를 허용하여 모든 것이 잘 작동하도록 할 수 있습니다. 어떤 도움이라도 대단히 감사하겠습니다.
#!/bin/bash
ROOTPATH="/Volumes/ARC-RAID/STORAGE/ASSET-Processing/Movies/LANDSCAPE/BRAND-RECOVERED/BRAND-RECOVERED-LANDSCAPE "
for subdir in *; do
cd ${ROOTPATH}/${subdir}
mkdir 00errors
for path in *.{MOV,mov,MP4,mp4}; do
ffmpeg -i "${path}" -f null -; echo$?
RC=$?
if [ "${RC}" -ne "0" ]; then
# Do something to handle the error.
mv ${path} ./00errors
fi
done
cd ../
done
답변1
코드를 자세히 살펴보지 않았지만 다음을 사용하는 것이 좋습니다 find
.
#!/bin/sh
topdir=/Volumes/ARC-RAID/STORAGE/ASSET-Processing/Movies/LANDSCAPE/BRAND-RECOVERED/BRAND-RECOVERED-LANDSCAPE
find "$topdir" -name 00error -prune -o \
-type f \( -iname '*.mp4' -o -iname '*.mov' \) \
! -exec ffmpeg -i {} -f null /dev/null \; \
-execdir mkdir -p 00error \; \
-execdir mv -- {} 00error \;
또는 다음 에서 짧은 인라인 sh
스크립트를 호출합니다 find
.
#!/bin/sh
topdir=/Volumes/ARC-RAID/STORAGE/ASSET-Processing/Movies/LANDSCAPE/BRAND-RECOVERED/BRAND-RECOVERED-LANDSCAPE
find "$topdir" -name 00error -prune -o \
-type f \( -iname '*.mp4' -o -iname '*.mov' \) -exec sh -c '
for pathname do
if ! ffmpeg -i "$pathname" -f null /dev/null; then
dirpath=${pathname%/*}
mkdir -p "$dirpath"/00error
mv "$pathname" "$dirpath"/00error
fi
done' sh {} +
두 변형 모두 파일 이름의 대소문자를 구분하지 않는 일치를 find
이해하는 패턴이 있고 찾은 파일의 디렉터리에서 유틸리티를 실행할 것임을 이해한다고 가정합니다. 둘 다 비표준입니다 .-iname
-execdir
-iname
-execdir
이는 최상위 디렉토리 아래의 모든 영화 파일을 선택하므로 스크립트만큼 디렉토리 구조가 엄격하지 않습니다.
귀하의 코드와 관련하여 :
제가 알아낸 값은
ROOTPATH
끝에 공백이 있습니다. 이는 우연일 수 있습니다.echo$?
echo0
과 사이의 누락된 공간으로 인해 유사하거나 유사한 작업이 시도됩니다 .echo1
echo
$?
$?
위의 오타를 수정하면 종료 상태로 쉘을 덮어쓰게 되므로 종료 상태가 나중에 반영되는 대신echo
종료 상태가 반영됩니다 .$RC
ffmpeg
echo
명령의 종료 상태를 별도의 변수에 저장한 다음 0에 대해 테스트하는 대신 명령문에서 직접 명령을 사용하십시오
if
. 위 명령의 두 번째 변형에서 이 작업을 수행했습니다find
.*
디렉터리 이름과 디렉터리가 아닌 이름을 일치시킬 수 있습니다. 따라서 사용이cd ${ROOTPATH}/${subdir}
실패할 수 있습니다(디렉토리 끝의 공백 등 디렉토리 이름에 공백이 있거나ROOTPATH
디렉토리가 비어 있기 때문에 실패할 수도 있음). 실패 하면cd
내부 루프가 잘못된 파일을 처리하고 있을 수 있으며 더cd ..
아래로 내려가면 레벨이 너무 높아집니다.
다음은 수정된 코드 변형입니다.
#!/bin/bash
topdir=/Volumes/ARC-RAID/STORAGE/ASSET-Processing/Movies/LANDSCAPE/BRAND-RECOVERED/BRAND-RECOVERED-LANDSCAPE
# Make globbing case-insensitive (nocaseglob), and
# make patterns disappear if not matched (nullglob)
shopt -s nullglob nocaseglob
for subdir in "$topdir"/*/; do
for mov in "$subdir"/*.{mov,mp4}; do
if [ -f "$mov" ] && ! ffmpeg -i "$mov" -f null /dev/null; then
mkdir -p "$subdir"/00error &&
mv "$mov" "$subdir"/00error
fi
done
done
보시다시피, cd
필요하지 않습니다.
내부 루프가 없는 경우:
#!/bin/bash
topdir=/Volumes/ARC-RAID/STORAGE/ASSET-Processing/Movies/LANDSCAPE/BRAND-RECOVERED/BRAND-RECOVERED-LANDSCAPE
shopt -s nocaseglob nullglob
for mov in "$topdir"/*/*.{mov,mp4}; do
if [ -f "$mov" ] && ! ffmpeg -i "$mov" -f null /dev/null; then
mkdir -p "${mov%/*}"/00error &&
mv "$mov" "${mov%/*}"/00error
fi
done