mp4
나는 많은 양의 비디오에서 프레임을 추출하여 다음과 같이 저장하는 스크립트를 가지고 있습니다 .png
for i in *.mp4; do
[ -f "$i" ] || break
number=$(echo "$i" | grep -o -E '[0-9]+')
name=frame"$number".png
ffmpeg -i "$i" -ss 00:01:00.000 -vframes 1 "$name"
done
동영상 이름은 등과 유사합니다 video1.mp4
. video2.mp4
루프가 비디오를 섞기 때문에 비디오에서 숫자를 추출하여 출력 파일 이름을 생성합니다.
이것은 잘 작동하지만 파일 이름은 다음 png
과 같습니다.
frame1?4.png
, frame3?4.png
, frame3?4.png
...
왜 ?4
?
아, 이제 보니 mp4의 4에서 4가 나오네요. 첫 번째 숫자만 어떻게 얻을 수 있나요?
답변1
이는 파일 이름에 포함된 줄 바꿈 ?
에 대한 자리 표시자 출력일 뿐입니다 .ls
echo foo3bar.mp4 | grep -Eo '[0-9]+'
출력됩니다:
3
4
파일 이름에 하나 이상의 십진수로 구성된 두 개의 시퀀스가 포함되어 있기 때문입니다.
대신 다음과 같이 할 수 있습니다.
for file in *[0-9]*.mp4; do
n=${file%.*} # remove the extension
n=${n%"${n##*[0-9]}"} # remove anything after the last digit
n=${n##*[!0-9]} # remove everything up to the last non-digit.
ffmpeg...
done
이렇게 하면 파일 이름에서 가장 오른쪽의 10진수 시퀀스를 추출하고 확장자를 제거하여 각 파일에 대해 여러 명령을 실행하지 않아도 됩니다.
bash
이 코드는 표준 POSIX sh 구문만 사용하므로 실행할 필요가 없습니다 . bash
또는 기타 ksh93
유사한 셸에서 파일의 루트 이름에 일련의 숫자만 포함되어 있다는 것을 알고 있는 경우 다음을 사용할 수도 있습니다 .
n=${file%.*} # remove the extension
n=${n//[^0-9]} # remove all non-digit characters
특정 기능이 있습니다 bash
:
[[ $file =~ ([0-9]+).*\. ]] && n=${BASH_REMATCH[1]}
추출합니다맨 왼쪽루트 이름의 숫자 순서입니다.
그리고 zsh
:
n=${(SM)${file:r}##<->}
답변2
파일 이름 4
에서 확장자를 올바르게 식별했습니다 . .mp4
물음표는 ls
각 일치 항목 사이에 삽입된 줄 바꿈을 표시할 수 있습니다(덧붙여서 grep -o
이것이 표시된 파일 이름을 신뢰할 수 없는 이유 중 하나입니다).ls
확장자 앞의 첫 번째 숫자 또는 마지막 숫자를 추출하려면 .mp4
다음을 수행하십시오.
n=${i%.mp4}
number=${n##*[!0-9]}
이렇게 하면 먼저 이름에서 확장자를 제거한 i
다음 이름 시작 부분에서 숫자가 아닌 모든 문자를 제거합니다.