Announcement

Collapse
No announcement yet.

Rename files matching a specific pattern

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Rename files matching a specific pattern

    I'm trying to organize my CD collection that I've burned to my server, mostly because it works better on my media player if the filenames follow a certain structure. Unfortunately, I'd burned these over several years using different tools and my file naming convention fell lax. Plus I bought sime music on-line in digital format so it's named the way the service names them, and they're not all the same.

    Here's what I have:
    2000+ files distributed among a few hundred directories (artist/album)
    They are mostly mp3 or flac
    They mostly are named "01 Songtitle" or "01 - Songtitle" plus their file type, however some are named "1 - Songtitle" or "1 Songtitle"
    In these folders are also other types of files like cover art and m3u playlists which I want to ignore (not rename)

    What I'd like to accomplish is renaming them all to to "01 - Songtitle".

    I'm assuming I have two tasks:
    If the filename starts with "number/space" then insert a leading zero, then;
    If the filename starts "number/number/space/letter" then insert "space/dash" after the second number.

    I've been doing this manually, but it's quite tedious so I'm looking to boost the time to finish this task. I'm assuming I can do this with either sed or find but I haven't figured out the magic sauce yet.

    Any "Masters of Bash" out there willing to point me in the right direction?

    I'm willing to accept a few hiccups like an album that starts with a number - I can manually find those and temporarily move them out of the way. I suppose if I use find I can just act on filenames which might solve that.

    Please Read Me

    #2
    So it looks like these do something:

    find . -type f -name '[0-9][0-9] [A-Z] *'

    seems to list all the files with 2 numbers and no dash, and this

    find . -type f -name '[0-9] [A-Z] *'

    seems to list all the files with a single number and no dash. Of course both ignore any song that starts with a number.

    Please Read Me

    Comment


      #3
      This gets me all the single number songs dash or no dash:

      find . -type f -name '[0-9] *'

      which accomplishes the first task - to find all those that start with a single digit. Should be simple enough to prepend a zero.

      EDIT:

      This command:

      find . -type f -name '[0-9] *' -exec rename 's/^/0/' {} +

      the "rename" command worked on a test, but within find it's failing because it's trying to append the path rather than just the file name.
      Last edited by oshunluvr; Feb 04, 2020, 09:59 AM.

      Please Read Me

      Comment


        #4
        I'd cheat :
        man mp3rename
        Assuming that the files are tagged of course.

        Comment


          #5
          I tried a couple other things. It looks like to problem is find returns the filename as;

          ./1 filename.mp3

          and then the rename or mv command tries to make it;

          0./1 filename.mp3

          and fails with "file not found".

          Please Read Me

          Comment


            #6
            Originally posted by claydoh View Post
            I'd cheat :
            man mp3rename
            Assuming that the files are tagged of course.
            Unfortunately, not all are mp3 and not all are tagged. I'm running them all through Picard to fill in the tags, but I also need to correct the filenames.

            Please Read Me

            Comment


              #7
              The weird thing is if I run find without -exec it lists the files like;

              folder/filename.mp3

              but if I add "-execdir bash -c" so I can execute a command, it lists them like;

              ./filename.mp3

              the leading dot-slash causing the issue. I really need the full path I think.

              Please Read Me

              Comment


                #8
                OK, more than one way to flog a horse. I gave up the one liner and got this to add the "0";

                Code:
                #!/bin/bash
                OIFS="$IFS"
                IFS=$'\n'
                for f in `find . -type f -name '[0-9] *'` 
                do 
                filename="${f##*/}" 
                path="${f%/*}/"
                mv  $path$filename $path"0"$filename
                done
                IFS="$OIFS"
                Maybe not pretty, but it worked.

                EDIT: I found 3 songs that started with a digit, so I manually fixed those after running the script. Now on the adding the dash...
                Last edited by oshunluvr; Feb 04, 2020, 10:56 AM.

                Please Read Me

                Comment


                  #9
                  There's a simple command called basename that looks prettier (at least to me). It strips off any path leading characters in a pathname.
                  Code:
                  $ basename ./file.txt
                  file.txt

                  Comment


                    #10
                    Originally posted by andystmartin View Post
                    There's a simple command called basename that looks prettier (at least to me). It strips off any path leading characters in a pathname.
                    Code:
                    $ basename ./file.txt
                    file.txt
                    Yeah, I am aware of that one but I needed the path too so I just used globbing.

                    So also un-pretty but functional, this has worked to add the dash. I'm 100% sure there's a better way, but since this is a one-time only I just needed it to work;

                    Code:
                    #!/bin/bash
                    OIFS="$IFS"
                    IFS=$'\n'
                    for f in `find . -type f -name '[0-9][0-9] *'`
                    do
                    origpath=$PWD
                    filename="${f##*/}" 
                    path="${f%/*}/"
                    cd $path
                    if [[ ! $filename =~ ^...[-] ]] 
                    then mv "$filename" "${filename:0:3}- ${filename:3}"
                    fi
                    cd $origpath
                    done
                    IFS="$OIFS"
                    I pulled all the filenames starting with 2 numbers regardless if they had a dash or not, then acted only on those without a dash. Worked pretty well even though it's messy looking.
                    Last edited by oshunluvr; Feb 04, 2020, 01:49 PM.

                    Please Read Me

                    Comment


                      #11
                      IMO the easiest way to do this sort of thing is to exploit one's editor search and replace skills. It's much safer too; get a bulk rename wrong and effectively you might have deleted or made inaccessible lots of files.

                      First, use a command to write all the file names to a file, maybe find * -type f > names. Then, in an editor put quotes around all the names, make a copy of all the names, make changes to the copy, then use a block cut and paste to put the new names beside the old. Use a block insert to put "mv " in front of every line, and check and recheck the result. Then source the file in bash.

                      Mistakes are easily undone, and exceptions can be fixed up before committing changes to your files.
                      Regards, John Little

                      Comment


                        #12
                        I was waiting for you to do this for me John, Or at least make it better!

                        But yes, I dumped a files list just in case the whole thing went sideways. I ended up copying a set of files and folders as a test before I ran it on the whole file system so I was safe.

                        Funny thing - I've been using MusicBrainz Picard to do the tagging. Turns out it has a whole scripting section and it's very powerful. It will rename the files as I tag them. I will be donating to that project as soon as I can.

                        Still, I enjoyed the exercise.

                        Please Read Me

                        Comment

                        Working...
                        X