Reputation: 3
I have a directory of mp3 files which are all named 1.mp3, 2.mp3 etc..
#dir with numbers for names
10.mp3 15.mp3 2.mp3 24.mp3 29.mp3 33.mp3 38.mp3 42.mp3 47.mp3 51.mp3 56.mp3 60.mp3 65.mp3 7.mp3 74.mp3 79.mp3 83.mp3 88.mp3 92.mp3
11.mp3 16.mp3 20.mp3 25.mp3 3.mp3 34.mp3 39.mp3 43.mp3 48.mp3 52.mp3 57.mp3 61.mp3 66.mp3 70.mp3 75.mp3 8.mp3 84.mp3 89.mp3 93.mp3
12.mp3 17.mp3 21.mp3 26.mp3 30.mp3 35.mp3 4.mp3 44.mp3 49.mp3 53.mp3 58.mp3 62.mp3 67.mp3 71.mp3 76.mp3 80.mp3 85.mp3 9.mp3 94.mp3
13.mp3 18.mp3 22.mp3 27.mp3 31.mp3 36.mp3 40.mp3 45.mp3 5.mp3 54.mp3 59.mp3 63.mp3 68.mp3 72.mp3 77.mp3 81.mp3 86.mp3 90.mp3 95.mp3
14.mp3 19.mp3 23.mp3 28.mp3 32.mp3 37.mp3 41.mp3 46.mp3 50.mp3 55.mp3 6.mp3 64.mp3 69.mp3 73.mp3 78.mp3 82.mp3 87.mp3 91.mp3 96.mp3
I wrote a for loop to extract the title from the metadata using ffmpeg:
for x in *.mp3; do
ffmpeg -i $x ./$("ffmpeg -i $x 2>&1 |grep -E '^\s*title\s*\:\s.*$' |awk -F ' :' '{print $2}'".mp3
done
Instead of extracting the title and renaming the file it says that the file '.mp3' already exists, would I like to rewrite it. when I type y to rewrite this new '.mp3' the same things just happens again. I fixed the problem by putting the full path of the output file in double quotes instead of just the title extraction command
for x in *.mp3; do
ffmpeg -I $x "./$(ffmpeg -i $x 2>&1 |grep -E '^\s*title\s*\:\s.*$' |awk -F ' :' '{print $2}'
)".mp3
done
My question is why does it create a new file called .mp3 when I only wrap the title extraction command in quotes and not the whole path?
I'm sorry if this is a little lengthly, Im new to stack overflow
Upvotes: 0
Views: 789
Reputation: 22012
In the command substitution $(command)
, you should not wrap the command
with double quotes as $("command")
especially when the command includes
options and/or pipeline sequences, because the double-quoted string is
treated as a single command.
Please see the difference of
echo $("ls")
and
echo $("ls -la")
The 1st one will work but the 2nd one does not, because bash
interpretes
ls -la
as a single command, not the ls
command followed by -la
option.
BTW if you just want to rename the files, without re-encoding (which may degrade the quality), you can say:
for f in *.mp3; do
title=$(ffmpeg -i "$f" 2>&1 | awk '/title/ {sub(/.*title\s*:\s*/, ""); print; exit}')
mv -i -- "$f" "$title".mp3
done
The last exit
is for the edge case the mp3 file includes multiple title
metadata.
[Update]
As @llogan comments, the ffprobe
is more robust to extract the media information
of the file. Please try instead:
for f in *.mp3; do
title=$(ffprobe -v error -of csv=p=0 -show_entries format_tags=title "$f")
mv -- "$f" "$title".mp3
done
Upvotes: 1