私の質問は、私のNASの音楽エンコーディングとLinuxコマンドの最適化に関するものですfind
。
私は完璧に動作するスクリプトを書いたが、それが最善のアプローチではないと確信しています。
結論として:
1/スクリプトは、エンコードするflacを含むディレクトリを確認します。
.flac
特定のファイルを含むすべてのディレクトリmp3/
または、名前のサブディレクトリを含まないディレクトリMp3/
特定の部分について私は次のようにしました。
FILE="./DirContaininfFlacToConvertToMp3.txt"
find . -type f -iname '*.flac' -printf '%h\n' | sort -u > fic1
find . -iname 'mp3' -type d | sort | sed 's/\/Mp3//' | sed 's/\/mp3//' > fic2
comm -3 fic1 fic2 > $FILE
- $ FILEは、これら2つの基準に一致するすべてのディレクトリを入力します。
fic1
ファイルにはflacファイルを含むすべてのディレクトリが含まれています。fic2
mp3/
ファイルには、mp3サブディレクトリを含むすべてのディレクトリが含まれています(sedは、commコマンドが機能するようにパスの末尾からまたはを削除するために使用されます)。Mp3/
comm -3
私の結果を私に与える$FILE
うまく動作しますが、最善の方法ではないと確信しています。照会パラメーターを使用するか、シェルに渡して最適化します。
2/スクリプトはflacファイルをエンコードしてMp3 /サブディレクトリに移動します。
file( $FILE
) が次の基準に一致するディレクトリ結果を提供する場合は、次のようにします。
mp3
定義されたディレクトリにファイルをエンコードします。Mp3
(元の構造を維持)というサブディレクトリに移動しました。
この部分では、2つのループで行われました。
#1st loop to encode
IFS=$'\n'
for next in `cat $FILE`
do
find $next -type f -name "*.flac" -exec ffmpeg -i {} -qscale:a 2 -map_metadata 0 -id3v2_version 3 {}.mp3 \;
done
#2nd loop for moving to subdir
for next in `cat $FILE`
do
find $next -type f -name '*.flac.mp3' -execdir mkdir -p Mp3 \; -execdir mv {} Mp3/ \;
done
また、2つのループ反復を避けることができると確信しています。
しかし、ここでは任意の目的で完全なスクリプトを見つけることができます(コーディングがあまり良くないことを知っています... :-(
フルスクリプト
#!/bin/bash
# Convert .flac en .mp3 file for Synology with ffmpeg
# usage : 1st construct list of directory to convert : run: ./script.sh V
# 2nd verify and to convert run : nohup ./script C &
#result of list of directories to encode
FILE="./ToConvertToMp3.txt"
# parameter validation
if [ "$#" -ne "1" ]
then
echo "1 parameter required : ./script.sh (V)erify (C)onvert "
exit 1;
fi
# generate list of directory for encoding
if [ "$1" == "V" ]
then
echo "-------- VERIFY AND CONSTRUCT LIST -------"
#1 find dir that contains .flac file
find . -type f -iname '*.flac' -printf '%h\n' | sort -u > fic1
# for those directory search if there is some *mp3* subdir
IFS=$'\n'
for dirflac in `cat fic1`
do
find $dirflac -iname '*mp3*' -type d -exec dirname {} \; >> fic2
done
# sort and unicity
cat fic2 | sort -u > fic3
# final construc of the list of directory to encode
comm -3 fic1 fic2 > $FILE
rm -f fic1 fic2 fic3
echo "-----DIRECTORY TO CONVERT-------"
cat $FILE
echo "-------------------------------------"
exit 0
fi
# Converting .flav files from directories listed in $FILE
if [ "$1" == "C" ]
then
echo "-------- CONVERTING FLAC -------"
if [ -e $FILE ]; then
echo "$FILE exist : OK"
else
echo "$FILE does not exist Please (V)erification first"
exit 3
fi
if [ -s "$FILE" ]; then
echo "$FILE contains directories : OK"
cat $FILE
else
echo "$FILE is empty , nothing to do"
exit 2
fi
echo "-------- CONVERTING -------"
IFS=$'\n'
for next in `cat $FILE`
do
find $next -type f -name "*.flac" -exec ffmpeg -i {} -qscale:a 2 -map_metadata 0 -id3v2_version 3 {}.mp3 \;
album="$(basename $directory)-Mp3";
echo " Processing $directory : creating subdirectory : $album, moving files in progress"
find $directory -type f -name '*.flac.mp3' -execdir mkdir -p "$album" \; -execdir mv {} "$album/" \;
done
echo "-------- END OF CONVERSION -------"
# renaming $FILE with timestamp
ficdate=$(date +%Y%M%d-%Hh%m);
mv $FILE $FILE-$ficdate.done;
exit 0
fi
echo "WARNING : 1 parameter : usage : ./script.sh (V)erification (C)onversion"
答え1
次のことができます。
find . -type f -name '*.flac' -execdir sh -c '
if [ ! -d mp3 ] && [ ! -d Mp3 ]; then
for file do
ffmpeg -i "$file" -qscale:a 2 -map_metadata 0 -id3v2_version 3 "${file%.*}.mp3"
done
fi' sh {} +
アイデアは、-execdir cmd {} +
(一部のGNUバージョンの場合find
)withが、指定されたディレクトリで一致するすべてのファイルに対して実行されることですfind
。cmd
私は言ったGNU Findのいくつかのバージョン以前はそれはうまくいきましたが、後でいくつかのバージョンで破損し(各ファイルが使用したかのように呼び出されますfind
)、それ以降のバージョンで修正されました。cmd
-execdir cmd {} \;
持っていることを確認できます。正しいバージョン:
find . -execdir echo {} +
正しいバージョンの場合はディレクトリごとに1行をインポートする必要があり、より正確なバージョンではファイルごとに1行をインポートする必要があります。
正しいバージョンがあり、ディレクトリごとに何千ものflacファイルがない場合は、両方を同時に実行できます。
find . -type f -name '*.flac' -execdir sh -c '
if [ ! -d mp3 ] && [ ! -d Mp3 ]; then
mkdir Mp3 || exit
for file do
ffmpeg -i "$file" -qscale:a 2 -map_metadata 0 -id3v2_version 3 "Mp3/${file%.*}.mp3"
done
fi' sh {} +