我的问题与我的 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
file 包含包含 flac 文件的所有目录。fic2
文件包含所有包含 mp3 子目录的目录(sed 用于消除路径末尾的mp3/
或以使 comm 命令起作用)Mp3/
comm -3
向我提供我的结果$FILE
它工作正常,但我很确定这不是最好的方法,只需使用查找参数或将其传递给 shell 即可对其进行优化。
2/ 脚本对 flac 文件进行编码并移动到 Mp3/ 子目录
一旦文件 ( $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 {} +
这个想法是, with -execdir cmd {} +
, (对于某些版本的 GNU find
),将为给定目录中的所有匹配文件find
运行。cmd
我说某些版本的 GNU 查找因为它曾经是这样工作的,但后来在某些版本中被破坏了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 {} +