大規模な音楽コレクションでM4AからOGGへの大量変換をしようとすると、私は次のようになります:
#!/bin/sh
for i in `find /home/family/Music -name *.m4a -print0`
#do ffmpeg -i "$i" -acodec libvorbis -aq 6 -vn -ac 2 "$i.ogg";
do echo $i
done
すべてのファイルの名前にはスペースが含まれます。上記の出力では、次のような単一のファイルが表示されます。
/home/family/Music/The
Kooks/Inside
In
_
Inside
Out/06
You
Don't
Love
Me.m4a
すべてのスペースが新しい行をマークするので、-print0
がこれを修正すると思いましたか?
これが、neverがfor
ループを使用して、出力にスペースを含めることができるコマンドを反復処理する理由の1つです。特にその出力が、/
と\0
を除くanythingを含むことができるファイル名のリストである場合。 bash pitfall number 1 に陥りました。代わりに常にwhile
を使用してください。スペース、改行、タブ、バックスラッシュ、その他の奇妙な文字を含むすべてのファイル名で動作することを確認するには、これを使用します:
find /home/family/Music -name '*.m4a' -print0 | while IFS= read -r -d '' file; do
ffmpeg -i "$file" -acodec libvorbis -aq 6 -vn -ac 2 "${file%.m4a}.ogg";
done
*.mp4a
を引用したことに注意してください。これにより、find
に渡す前にbashが展開しないことが保証されます。これは、現在のディレクトリにそのグロブに一致するファイルがある場合に重要です。
おそらくご存じのとおり、-print0
を使用すると、find
によって結果が改行ではなく\0
で区切られます。
IFS=
:これにより、入力フィールドの文字が何も設定されず、Wordの分割が行われなくなります。
while read -r -d '' file
:これは結果を反復し、for file in $(command)
と同様にそれぞれを$file
として保存します。オプションは(help read
から)です:
-r do not allow backslashes to escape any characters
-d delim continue until the first character of DELIM is read, rather
than newline
区切り文字を空の文字列(-d ''
)に設定すると、read
がfindの-print0
でNiceを再生します。
"${file%.mp3}.ogg";
:これは、単に.m4a
サフィックスを削除し、.ogg
に置き換えることで、foo.ogg
の代わりにfoo.m4a.ogg
を取得します。
残りはあなたが試みたものと同じなので、あなたはそれを理解していると思います。
xargs
を-0
オプションとともに使用するか、または find
の独自のexec
オプションを使用します。
find /home/family/Music -name '*.m4a' -exec ffmpeg -i "{}" -acodec libvorbis -aq 6 -vn -ac 2 "{}.ogg" \;
# or:
find /home/family/Music -name '*.m4a' -print0 | xargs -0 -i ffmpeg -i {} -acodec libvorbis -aq 6 -vn -ac 2 {}.ogg
両方の場合(および元のコマンド)で、x.m4a
はx.m4a.ogg
に変換されることに注意してください。
これはあなたが望むものの解決策かもしれません
#!/bin/bash
find /home/family/Music -type f -name '*.m4a' -print0 | while IFS= read -r -d '' i;
do
#do ffmpeg -i "$i" -acodec libvorbis -aq 6 -vn -ac 2 "$i.ogg";
echo $i
done