スペースを含むファイル名をバッチ処理して拡張子を変更する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.opus1つのコマンドにファイルを変換する

部分的に動作するスクリプトは、空白があっても、現在のディレクトリで.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

関連情報