.mkv
하위 폴더가 있는 폴더 구조의 모든 파일을 .mp4
.
현재 폴더에만 적용되는 표준 줄이 표시됩니다.
for video in *.mkv; do ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4; rm "$video"; done
그래서 나는 다음과 같은 것을 만들 것이라고 생각했습니다.
for video in $(find . -name *.mp4); do ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mkv; rm "$video"; done
그러나 공백이 포함된 폴더에서는 실패하는 것 같습니다. 누구든지 내 실수를 지적할 수 있나요?
답변1
귀하의 실수는 find
명령 대체를 사용하는 것입니다. 명령 대체는 항상 단일 문자열을 생성합니다. 대체 항목을 따옴표로 묶지 않으면 문자열이 공백, 탭 및 줄 바꿈(기본적으로)으로 분할됩니다. 분할된 단어는 파일 이름 글로빙을 위해 처리됩니다. 결과 문자열은 루프가 반복되는 문자열이며, 이는 원하는 문자열이 아닙니다.
현재 디렉터리에서 작동하는 루프(대시로 시작하는 파일 이름 문제를 해결하기 위해):
for video in ./*.mkv; do
ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4
rm "$video"
done
globbing 모드를 활성화하여 재귀적으로 작동하도록 변경되었습니다( 일치 항목이 없을 때 루프가 완전히 실행되는 것을 방지하기 위해 **
사용 ).nullglob
shopt -s globstar nullglob
for video in ./**/*.mkv; do
ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4
rm "$video"
done
위의 두 루프는 파일 유형을 고려하지 않으며 ffmpeg
이름이 지정된 패턴과 일치하는 한 심볼릭 링크, 디렉토리 또는 기타 비 전통적인 유형의 파일을 기꺼이 제공합니다.
또는 경로 이름의 재귀 생성을 다음 대상에 위임합니다 find
(일반 파일만 선택):
find . -name '*.mkv' -type f -exec sh -c '
for video do
ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4
rm "$video"
done' sh {} +
위의 코드는 또한 패턴과 일치하는 숨겨진 이름을 찾습니다. 이는 처음 두 개의 쉘 루프가 수행하지 않는 것입니다( dotglob
쉘 옵션이 활성화되지 않은 경우).
기타 관련 질문: