내 질문은 내 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은 이 두 가지 기준과 일치하는 모든 디렉터리를 채웁니다.
fic1
파일에는 flac 파일이 포함된 모든 디렉터리가 포함되어 있습니다.fic2
mp3/
파일에는 mp3 하위 디렉터리가 포함된 모든 디렉터리가 포함되어 있습니다(sed는 comm 명령이 작동하도록 경로 끝에서 또는 를 제거하는 데 사용됩니다 ).Mp3/
comm -3
내 결과를 나에게 제공$FILE
잘 작동하지만 최선의 방법은 아니라고 확신합니다. 조회 매개변수를 사용하거나 이를 셸에 전달하여 최적화하면 됩니다.
2/ 스크립트는 flac 파일을 인코딩하여 Mp3/ 하위 디렉터리로 이동합니다.
file( $FILE
)이 다음 기준과 일치하는 디렉터리 결과를 제공하면 다음을 수행합니다.
mp3
정의된 디렉터리에 파일을 인코딩합니다.Mp3
(원래 구조 유지) 라는 하위 디렉토리로 옮겼습니다.
이 부분에서는 두 가지 루프로 수행했습니다.
#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 {} +
올바른 버전의 경우 디렉터리당 한 줄을 가져와야 하고, 덜 정확한 버전의 경우 파일당 한 줄을 가져와야 합니다.
올바른 버전이 있고 디렉터리당 수천 개의 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 {} +