YYYY-MM-DD/VIDEOCHANNELNUMBER-EVENTIMERANGE.mp4
날짜별, 카메라 채널별, 이벤트 시간별( ) 별로 나누어진 영상 파일이 많습니다.
/2021-07-03/ch2_main_20210703074010_20210703074154.mp4
/2021-07-03/ch2_main_20210703074156_20210703074357.mp4
/2021-07-03/ch2_main_20210703074446_20210703074537.mp4
/2021-07-03/ch2_main_20210703074618_20210703075119.mp4
/2021-07-03/ch2_main_20210703075153_20210703075312.mp4
/2021-07-03/ch2_main_20210703075337_20210703080422.mp4
이 클립을 날짜와 카메라 채널별로만 병합하고 싶습니다(예 /2021-04-03-CH1.mp4
:)
내 프로세스는 다음과 같습니다
- 각 날짜 폴더를 반복합니다(
for VIDEODIR in */
). - 각 폴더에서 각 채널 번호를 반복합니다(
for VIDEOCHANNELNUMBER in 1 2 3 4 5 6; do
). - 각 채널 번호별로 병합할 모든 비디오 파일을 찾습니다(
for f in $VIDEODIR/ch$VIDEOCHANNELNUMBER*.mp4 ; do
). - FFMPEG는 파일을 루트 디렉터리(
ffmpeg -i $VIDEOLIST -c copy "$DATE-CH$VIDEOCHANNELNUMBER.mp4"
) 에 병합하고 저장합니다. - 성공하면 모든 원본 클립의 디렉터리를 삭제합니다. (
if [ $? -eq 0 ]; then rm $VIDEODIR -r fi
)
어떤 이유로든 비디오 채널이 당일 오프라인 상태이고 일치하는 항목이 없으면 2단계가 잘못되어 막히게 됩니다. ( zsh: no matches found: /2021-07-03/ch1*.mp4
). 건너뛰고 계속하는 대신 전체 루프가 중단됩니다.
답변1
N
glob 한정자를 사용하여 일치하는 항목이 없을 경우 오류를 반환하는 대신 glob을 아무것도 확장하지 않도록 지정할 수 있으며 한정자를 사용하여 /
디렉터리 유형의 파일을 선택할 수 있습니다.
N
배열 변수에 할당할 때 일반적으로 한정자를 사용해야 합니다.
dirs=( *(N/) )
또는 반복할 때:
for dir in *(N/)
따라서 무엇을 하려는지 잘 모르겠지만 다음과 같이 보일 수 있습니다.
for dir in *(N/); do
for (( channel = 1; channel <= 6; channel++ )); do
files=( $dir/ch${channel}_*.mp4(N) )
if (( $#files )); then
ffmpeg ... $file
fi
done
done
여기에서는 한 번에 모든 파일을 반복하기 위해 다양한 접근 방식을 사용할 수 있습니다.
typeset -A list=()
for file (<1900-2100>-<1-12>-<1-31>/ch<1-6>_*.mp4(Nn))
files[$file:h-${${file:t}%%_*}.mp4]+=$file$'\0'
for output_file (${(k)list})
ffmpeg -i ${(0)list[$output_file]} -c copy $output_file &&
rm -f ${(0)list[$output_file]}
(그리고 rmdir <1900-2100>-<1-12>-<1-31>(/^F)
이후에 빈 디렉토리를 삭제합니다).
흥미롭게도 이것이 하는 일입니다 fish
. in과 같은 일치 항목이 없으면 glob이 , (변수에 할당됨) 또는 와 zsh
함께 사용되지 않는 한 glob에서 오류가 발생합니다 .for
set
count