私は現在、すべてのflacファイルをmp3ファイルに変換する小さなスクリプトを書こうとしています。ただし、すべての音楽フォルダにわたって再帰を設定しようとすると、いくつかの問題が発生します。スクリプトは現在のディレクトリ(.)として繰り返されます。
これが私が現在持っているものです:
#!/bin/bash
#---
# flacToMp3: Converts FLAC files in my originalFLAC folder into mp3 files
# and places them in an identical folder structure in my Music
# folder.
#---
function enterDIR {
for DIR in "$(find . -maxdepth 1 -type d)"; do #recurse into every directory below top-level directory
if [ "$DIR" == "." ]; then #avoid current directory infinite loop
continue
fi
cd "$DIR/"
enterDIR
done
createDirectory
convertFLAC
}
function createDirectory {
#recreate directory structure in Music folder
curDir="$pwd"
newDir=${curDir/originalFLAC/Music}
mkdir -p $newDir
}
function convertFLAC {
#convert each flac file in current directory into an mp3 file
for FILE in "$(find . -maxdepth 1 -type f)"; do #loop through all regular (non-directory) files in current directory
if [ "${FILE: -5}" == ".flac" ]; then #if FILE has extension .flac
ffmpeg -i "$FILE" -ab 320k -map_metadata 0 "${FILE%.*}.mp3"; #convert to .mp3
mv -u "${FILE%.*}.mp3" $newDir
else #copy all other files to new directory as-is
cp -ur "$FILE" $newDir
fi
done
}
enterDIR
このスクリプトは Bash が始まったばかりだったので、とても素朴です。問題(または少なくとも私が問題だと思うもの)はそのif [ "$DIR" == "." ]; then
行で発生します。スクリプトを実行するときに私の出力を見るとフィルタリングされないようです。
現在のディレクトリをフィルタリング(無視)する方法は?
答え1
find
optionsを使用してフィルタリングできます-mindepth
。このように:
function enterDIR {
find . -mindepth 1-maxdepth 1 -type d | while read DIR ;
do
#recurse into every directory below top-level directory
cd "$DIR/"
enterDIR
done
createDirectory
convertFLAC
}
しかし、スクリプト全体は良い解決策のようには見えません。
私が正しく理解したら、ディレクトリツリー全体をナビゲートし、新しいディレクトリを作成し、flacをmp3に変換し(存在する場合)、flac以外のすべてのファイルを新しいディレクトリにコピーしたいと思います。私はそうします:
find . -mindepth 1 -type -d -exec mkdir -p {}/originalFLAC/Music \+
find . -type f -iname "*.flac" -exec ffmpeg -i {} -ab 320k -map_metadata 0 {}.mp3 \;
find . -type f ! -iname "*.flac" | while read file ; do cp -v "$file" "$(dirname "$file")"/originalFLAC/Music/ ; done
答え2
これを交換してみてください
for DIR in "$(find . -maxdepth 1 -type d)"
これで
for DIR in "$(find . -maxdepth 1 -type d | grep -v "\.$")"
.
正規表現では、「すべて」単一文字として解釈されます。したがって、バックスラッシュでエスケープする必要があります。また、すべての行はドット文字で始まるため、ドットとドットのみを含む行を見つける必要があります。したがって、行末文字$
。
この時点では、if
次のブロックは必要ありません。
if [ "$DIR" == "." ]; then #avoid current directory infinite loop
continue
fi