Removing specific part of filename (what's after the second dash) for all files in a folder

Solution 1:

I would use the Perl-based rename command - for example, to remove the shortest sequence of word-characters starting with - ahead of the .mp3 suffix, you could try

rename -nv -- 's/-\w+?[.]mp3$/.mp3/' *.mp3

The n option runs the command in 'dry run' mode - if the matches appear correct, remove the n option and run it again.

Solution 2:

The part you don't want is the video id. You can use youtube-dl's output template functionality:

--output "%(title)s"

this will use only the title and omit the id. Run youtube-dl with no parameters to see other options.

You can fix your existing downloads:

for i in *; do mv "$i" `basename "$i" .mp3 | cut -f -2 -d "-"`.mp3; done

(This is equivalent to Jakke's answer).

Solution 3:

sed can accomplish this in a single line, albeit in a rather convoluted way.

ls | sed 's/\(.*\)\(-.*\)/mv \"&\" \"\1.mp3\"/' | bash

This first lists the files in the current directory (assuming all the files you want to rename are in the current directory), and then uses sed's s/regex/replacement command to generate a sensible mv command which is then piped to bash which executes it. This assumes all of your files are something of the form "A-C.mp3" or "A - B-C.mp3". Here is how it works:

The regex part of the sed command is

\(.*\)\(-.*\)

this "groups" the name into two groupings (delimited with escaped parentheses): one matching ".*" (any number of any character) and another matching "-.*", a dash followed by any number of any character. Notice that this matches the entire filename (in two groups). Also note that since "greedy" regex is used, the first group will match "A" in "A-C.mp3" and "A - B", not just "A ", in "A - B-C.mp3", as wanted.

The replacement part of the sed command is

mv \"&\" \"\1.mp3\"/

Note that an & character instructs sed to insert the entire pattern that matched regex, in this case that is the entire filename, and the \1 instructs sed to insert the part of the filename that matched the first grouping ".*". These two are combined with an preceding mv and a trailing .mp3, with escaped quotation marks to produce a sensible rename command. For example, for "A - B-C.mp3", the full sed command will produce:

mv "A - B-C.mp3" "A - B.mp3"

And finally all of this is piped to bash, which happily executes the mv (rename) command.

Solution 4:

You can check it with this command:

for i in *.mp3; do echo "$(echo $i|cut -d- -f1,2).mp3"; done

Note that you do have file names without 2 dashes, so it won't work for everything.

If you actually want to change the names,

for i in *.mp3
do
  newname="$(echo $i|cut -d- -f1,2).mp3";
  mv $i $newname
done