?4가 이 Bash 스크립트의 파일 이름에 추가됩니다. 이유는 무엇입니까?

?4가 이 Bash 스크립트의 파일 이름에 추가됩니다. 이유는 무엇입니까?

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다음 이름 시작 부분에서 숫자가 아닌 모든 문자를 제거합니다.

관련 정보