0

I batch-ripped my old CDs to Track1.mp3. The problem is Each CD directory has Track1.mp3 so when I move them to /Music, they overwrite!

Is there possibly a bash script or mv command to move .mp3s from multiple sub-directories with the same file name into a single directory while renaming them if that name exists already under LINUX?

1

Most likely you will want "friendly" renames. Let's assume you have a struckture like

Artist1-+
        +-AlbumA-+
        |        +-Track1.mp3
        |        +-Track2.mp3
        +-AlbumB-+
                 +-Track1.mp3
                 +-Track2.mp3
Artist2-+
        +-AlbumX-+
        |        +-Track1.mp3
        |        +-Track2.mp3
        +-AlbumY-+
        |        +-Track1.mp3
        |        +-Track2.mp3

You would now want the single directory to contain something like

Artist1-AlbumA-Track1.mp3
Artist1-AlbumA-Track2.mp3
...
Artist2-AlbumY-Track1.mp3
Artist2-AlbumY-Track2.mp3

This can be achieved with a simple bash loop

for M in */*/*.mp3; do
  TRACK=$(basename "$M")
  ALBUM=$(basename $(dirname "$M"))
  ARTIST=$(basename $(dirname $(dirname "$M")))
  mv "$M" "$TARGET_DIR/$ARTIST-$ALBUM-$TRACK"
done
  • 3.19.0-32-generic wouldn't allow for it: "basename: extra operand" and "mv: cannot stat ‘/*/.mp3’: No such file or directory." – Linux_User2019 Jun 25 '19 at 18:29
  • The path */*/*.mp3 is ment in connection with the example structure I gave - you might need to adapt it to your real structure. – Eugen Rieck Jun 26 '19 at 7:32
0

The cp and mv commands support this functionality through the --backup option.

From the manual:

   --backup[=CONTROL]
          make a backup of each existing destination file

   -b     like --backup but does not accept an argument

[...]

The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX. The version control method may be selected via the --backup option or through the VERSION_CONTROL environment variable. Here are the values:

   none, off
          never make backups (even if --backup is given)

   numbered, t
          make numbered backups

   existing, nil
          numbered if numbered backups exist, simple otherwise

   simple, never
          always make simple backups

So e.g. mv --backup=t <source_file> <dest_file> should work.

  • "mv: cannot stat ‘*.mp3’: No such file or directory." This didn't work. It failed to search for files in subdirectories. – Linux_User2019 Jun 25 '19 at 18:43
  • Try to write a loop around it and it will work. – mcserep Jun 25 '19 at 20:01
0

According to the linux community and commandlinefu.com, this convenient feature isn't possible whatsoever in any versions to date.

There is currently no command and no sure way via commandline to move files from multiple directories & subdirectories having the same name, into a single directory, without overwriting them.

Sources: commandlinefu.com, askubuntu.com, linuxquestions.org, superuser.com

0

I assume you have a folder structure like this:

$ tree .
.
├── artist1
│   ├── albuma
│   │   └── Track1.mp3
│   └── albumb
│       └── Track1.mp3
└── artist two
    ├── album one
    │   └── Track1.mp3
    └── album two
        └── Track1.mp3

First, cd to the parent folder of your MP3 collection (parent folder of artist1).

Now if you run the following find command, you will see output like this:

$ find . -name '*.mp3' -exec bash -c 'echo mv -v "$1" /tmp/music/$(echo "$1" | sed "s/\.\///" | tr " /" "-")' bash {} \;
mv -v ./artist two/album one/Track1.mp3 /tmp/music/artist-two-album-one-Track1.mp3
mv -v ./artist two/album two/Track1.mp3 /tmp/music/artist-two-album-two-Track1.mp3
mv -v ./artist1/albuma/Track1.mp3 /tmp/music/artist1-albuma-Track1.mp3
mv -v ./artist1/albumb/Track1.mp3 /tmp/music/artist1-albumb-Track1.mp3
  • find collects all paths to the MP3 files, e.g. ./artist two/album one/Track1.mp3 and passes them to bash via -exec
  • $(echo "$1" | sed "s/\.\///" | tr " /" "-") is used to modify the output filename. sed removes the first ./ and tr converts all space characters and / to -.

It is essential that you run find with . as start directory, otherwise the (relative) output path will not be modified correctly. Change /tmp/music/ to the path of your music library.

If the output looks good to you, then remove the first echo and execute the command again.

Output:

$ find . -name '*.mp3' -exec bash -c 'mv -v "$1" /tmp/music/$(echo "$1" | sed "s/\.\///" | tr " /" "-")' babbsh {} \;
'./artist two/album one/Track1.mp3' -> '/tmp/music/artist-two-album-one-Track1.mp3'
'./artist two/album two/Track1.mp3' -> '/tmp/music/artist-two-album-two-Track1.mp3'
'./artist1/albuma/Track1.mp3' -> '/tmp/music/artist1-albuma-Track1.mp3'
'./artist1/albumb/Track1.mp3' -> '/tmp/music/artist1-albumb-Track1.mp3'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.