나는 디렉토리에서 시작한 다음 (find 대신) fd와 ffmpeg를 사용하여 고정된 복사본을 내보내는 코드를 갖는 것에 꽤 가깝다고 생각합니다. 여기에 의사 코드로 if 문을 작성했습니다.
for i in $(fd -e .mp4 -e .avi);
do if [ffmpeg -v error -i "$i" -f null - 2] has an error, then
ffmpeg -err_detect ignore_err -i video.mkv -c copy video_fixed.mkv;
done
나는 "치명적"을 사용할 때 치명적인 오류가 없으면 파일이 비어 있거나 0이 될 것이라고 믿습니다. 어느 쪽이 더 쉬울지 모르지만 "오류"가 더 적절하다고 생각합니다.
수정하고 싶은 것은 오류가 있으면 IF 문을 실행하고 오류가 없으면 아무것도 하지 않는 것입니다. 오류가 발생하면 video_fixed.mkv가 생성됩니다. 그러나 나는 또한 그것이 video_fixed.mkv가 되는 것을 원하지 않고, $i와 동일한 파일 이름과 원본 파일과 동일한 파일 확장자를 갖고 원본 파일을 그것으로 바꾸길 원합니다. 또한 $i가 단지 파일 이름인지 아니면 전체 경로를 포함하는 파일 이름인지 확실하지 않아서 문제가 발생합니다. 마지막 "/" 뒤의 문자열을 파일 이름으로 캡처해야 합니다.
비교하기가 너무 어려우면 오류 유무에 관계없이 모든 파일을 복사해야 하는데, 그러기 위해서는 복사본에 이름을 지정하고 덮어써서 원본과 동일하게 만들어야 합니다.
감사해요
답변1
아직 IF 문을 시도하지는 않았지만 충분히 진전되었습니다.
비디오 파일이 포함된 폴더에서 다음 명령을 실행하십시오.
모든 내용을 저장하려면 CorrectedVideos라는 중복 폴더를 만드세요.
IFS=$'\n'; find . -type d | xargs -I {} mkdir -p /home/Rob/Desktop/correctedVideos/{}; for i in $(fd -e .mp4 -e .avi); do ffmpeg -err_detect ignore_err -i "$i" -c copy "/home/Rob/Desktop/correctedVideos/$i"; done
여기서 i는 for 루프 또는 입력과 같은 변수이며 반드시 i가 아닌 모든 것이 될 수 있습니다.
파일 이름만 표시: ${i##*/}
현재 디렉터리의 파일 경로만 표시합니다: ${i%/*}
현재 디렉터리의 상대 파일 경로와 파일 이름이 표시됩니다: "$i"
따라서 "$i"는 ${i%/와 같습니다.}/${i##/}
"~"가 아닌 절대 경로를 사용해야 합니다.
PS 복사본이 포함된 병렬 폴더를 생성하지 않고 기존 폴더에 복사본을 생성하려는 경우 두 가지 방법이 있습니다.
방법 1: 단일 폴더의 각 파일에 대해(하위 폴더가 있는 경우 문제가 발생하므로 하위 폴더가 있는 폴더에서는 사용하지 마십시오):
IFS=$'\n'; for i in $(fd -e .mp4 -e .avi); do echo ffmpeg -err_detect ignore_err -i "$i" -c copy "copied_$i"; done
방법 2: 하위 폴더가 포함된 폴더의 경우 명령이 실행되는 최상위 폴더에 파일이 있으면 작동하지 않습니다.
IFS=$'\n'; for i in $(fd -e .mp4 -e .avi); do ffmpeg -err_detect ignore_err -i "$i" -c copy "$PWD/${i%/*}/copied_${i##*/}"; done