공백이 포함된 파일 이름을 일괄 처리하고 확장자를 바꾸는 ZSh 스크립트

공백이 포함된 파일 이름을 일괄 처리하고 확장자를 바꾸는 ZSh 스크립트

음악 형식의 카탈로그 파일을 Ogg opus 형식으로 변환할 수 있는 zsh 스크립트가 있습니까? 이것파일 이름에 공백이 포함되어 있습니다..

예를 들어, 디렉토리에는 확장자가 *.wma인 파일 10개가 포함되어 있습니다.

*.wav다음을 사용하여 파일을 형식 으로 변환ffmpeg -i filename.wma filename.wav

파일은 *.wav프로덕션에 사용하기 위해 변환됩니다.opusenc --bitrate 160 filename.wav filename.opus

고쳐 쓰다: ffmpeg -i filename.wma -c:a libopus -b:a 128k filename.opus하나의 명령으로 파일을 변환합니다

부분적으로 작동하는 스크립트는 공백이 있어도 현재 디렉터리에서 .wma에서 .wav까지 파일 이름을 처리합니다. 그러나 .wav*.wma 파일 확장자를 바꾸는 대신 확장자가 추가됩니다.

스크립트는 이라는 파일에 추가되고 convert파일은 실행 가능해집니다.

IFS=$'\n'
for x in *.wma ; do
  echo $x
  ffmpeg -i "$x" $x.wav
done

사용해 보세요Zsh 수정자파일 확장자를 다음으로 바꾸십시오. ( ${x:e}".wavilkkachu의 제안 후에 이것을 시도했습니다 ${x:r}".wav)

IFS=$'\n'
for x in *.wma ; do
  ffmpeg -i "$x" "${x:e}".wav
done

이름이 지정된 파일에서 이를 호출하면 convert다음 오류가 반환됩니다.

./convert: 3: Bad substitution

에서도 같은 오류가 발생합니다.

IFS=$'\n'
for x in *.wma ; do
  ffmpeg -i "$x" "${x:r}".wav
done

구문이 작성하기가 매우 쉽지 않거나 파일 이름에 공백이 있으면 수정자가 작동하지 않는 것 같습니다. 아니면 아직 zsh에 대해 배울 것이 많습니다 :)

Zsh에서 파일 확장자를 바꾸는 올바른 방법이 있습니까(파일 이름에 공백이 포함된 경우)

감사해요.

답변1

sh문제는 스크립트를 in 이 아닌 zshin 으로 해석한다는 것이지만 zsh여기서는 다음을 사용할 수 있습니다 zmv.

#! /bin/zsh -
autoload zmv
zmv -P ffmpeg -o -i './(*).wma' './$1.wav'

zmv일반적으로 일괄 이름 바꾸기가 수행되지만 일괄 복사/링크 또는 모든 작업의 ​​일괄 작업을 수행하는 것도 가능합니다(작업을 수행하는 명령의 이름이 제공되는 경우).아무것.

작업을 수행하기 전에 수행하는 몇 가지 보호 조치(대상 파일이 존재하지 않는지 또는 두 소스 파일이 동일한 대상에 매핑되는지 확인)의 이점을 누릴 수 있습니다.

또한 ./.-ffmpeg

어쨌든 IFS 토큰화를 사용하지 않고( 명령 대체 및 zsh에서만 수행됨) 배열 요소를 의 첫 번째 요소와 연결하는 것과 같은 것을 사용하지 않기 IFS=$'\n'때문에 코드에서는 아무 것도 수행되지 않습니다 . // 전역 변경을 수행하는 대신 매개변수 확장 플래그를 사용하여 분할하거나 결합하는 것이 좋습니다 . 또한 줄 바꿈은 파일 이름의 모든 문자로 유효합니다.$=param"$array[*]"$IFSzshs[sep]f0j[sep]$IFS

답변2

Zsh 수정자(및 기타 zsh 관련 구문)를 사용하려면 파일에 추가된 스크립트가 먼저 해당 파일을 zsh 스크립트로 정의해야 합니다.

#!/usr/bin/zsh

which zsh(선택 사항) 운영 체제가 이 위치를 사용하는지 확실하지 않은 경우 먼저 zsh의 위치를 ​​확인하세요.

이 줄을 추가하면 편집기에서 파일을 열 때 강조 표시되는 특정 zsh 구문도 추가됩니다.

쉘 변수 IFS(내부 필드 구분 기호)는 문자열 시퀀스(예: 디렉토리 목록)를 분할할 때 단어 경계가 인식되는 방법을 결정합니다.

$'\n'공백이 포함된 파일 이름을 허용 하도록 zsh에서 IFS를 설정합니다.

IFS=$'\n'

for루프를 사용하면 현재 디렉터리 또는 현재 디렉터리 및 하위 디렉터리 *.wma의 해당 파일 확장자에 대해 와일드카드를 사용하여 현재 디렉터리의 모든 파일을 반복합니다.**/*.wma

#!/usr/bin/zsh

IFS=$'\n'
for x in *.wma ; do
  ffmpeg -i "$x" "${x:r}".wav
done

ffmpeg는 libopus오디오 코덱을 사용하여 opus 파일로 변환할 수 있으므로 opusenc 도구에서 지원하는 형식으로 변환할 필요가 없습니다.

ffmpeg -i original-file.wma -b:a 128k -c:a libopus ouptut-file.opus

-b:a오디오 비트 전송률은 어디에 있고 -c:a오디오 코덱은 어디에 있습니까?

이를 모두 종합하면 최종 스크립트는 다음과 같습니다.

#!/usr/bin/zsh

IFS=$'\n'
for x in *.wma ; do
  ffmpeg -i "$x" -b:a 128k -c:a libopus "${x:r}".opus
done

관련 정보