拡張子の名前を変更しようとしたときに交換エラーが発生しました。 [重複]

拡張子の名前を変更しようとしたときに交換エラーが発生しました。 [重複]

すべてのwavファイルとmp3ファイルをoggファイルに再帰的に変換するためにfindとFFmpegを使用しようとしています。これを行うには、次のbashスクリプトを作成しました。

#!/usr/bin/env bash

# Converts samples to ogg

find samples \( -iname '*.wav' -o -iname '*.mp3' \) -execdir ffmpeg -i "$(basename "{}")" -qscale:a 6 "${$(basename "{}")%.*}.ogg" \;

ただし、これを行うとエラーが発生します。

${$(basename "{}")%.*}.ogg: bad substitution

サフィックス付きのファイルのデフォルト名を返すように、最後の代替項目の形式をどのように指定する必要がありますか.ogg?これがうまくいかないのはなぜですか?

答え1

--execdir(Bash)シェルが呼び出され、次にffmpegが呼び出されると仮定しているようです。しかし、実際にはそうではありません。

   -exec command ;
          Execute  command;  true  if 0 status is returned.  All following
          arguments to find are taken to be arguments to the command until
          an  argument  consisting of `;' is encountered.  The string `{}'
          is replaced by the current file name being processed  everywhere
          it occurs in the arguments to the command, not just in arguments
          where it is alone, as in some versions of find.

ffmpeg呼び出され、findit(ffmpeg)は特別な構文で何をすべきかわかりません。

入力ファイル名のみに基づいて1つの変換を処理する小さなbashスクリプトを作成します-execdir

答え2

私は最近例を書きました。シェルワンライナーをfindコマンドに充填することも別のユースケースです。

変える:

find samples \( -iname '*.wav' -o -iname '*.mp3' \) -execdir ffmpeg -i "$(basename "{}")" -qscale:a 6 "${$(basename "{}")%.*}.ogg" \;

努力する:

find samples \( -iname '*.wav' -o -iname '*.mp3' \) -exec sh -c 'ffmpeg -i "$1" -qscale:a 6 "${1%.*}.ogg"' find-sh {} \;

これはfind-sh任意のテキストです。シェルの$0find-sh本当に良い名前だと思います。

関連情報