MenaK
MenaK

Reputation: 3

rename files from id3v1 tags in terminal

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

Answers (1)

tshiono
tshiono

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

Related Questions