.mkv
サブフォルダがあるフォルダ構造内のすべてのファイルを.mp4
。
現在のフォルダにのみ適用される標準行が表示されます。
for video in *.mkv; do ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4; rm "$video"; done
だから私は次のようなものを作ると思いました。
for video in $(find . -name *.mp4); do ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mkv; rm "$video"; done
しかし、空白を含むフォルダでは失敗するようです。誰でも私の間違いを指摘できますか?
ベストアンサー1
あなたの間違いは、find
コマンド置換を使用することです。コマンド置換は常に単一の文字列を生成します。代替項目を引用符で囲まないと、文字列はスペース、タブ、および改行(デフォルト)に分割されます。分割された単語はファイル名のグロービングのために処理されます。結果の文字列はループが繰り返される文字列であり、これは目的の文字列ではありません。
現在のディレクトリで動作するループ(ダッシュで始まるファイル名の問題を解決するため):
for video in ./*.mkv; do
ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4
rm "$video"
done
globbingモードを有効にして再帰的に動作するように変更されました(一致がない場合にループが完全に実行されるのを防ぐために使用されます**
)。nullglob
shopt -s globstar nullglob
for video in ./**/*.mkv; do
ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4
rm "$video"
done
上記の2つのループはファイルの種類を考慮しておらず、名前付きパターンとffmpeg
一致する限り、シンボリックリンク、ディレクトリ、または他の非伝統的な種類のファイルを喜んで提供します。
または、パス名の再帰生成を次の宛先に委任しますfind
(一般ファイルのみを選択)。
find . -name '*.mkv' -type f -exec sh -c '
for video do
ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4
rm "$video"
done' sh {} +
上記のコードはまた、パターンに一致する隠された名前を探します。これは、最初の2つのシェルループが実行しないことです(dotglob
シェルオプションが有効になっていない場合)。
その他の関連質問: