Announcement

Collapse
No announcement yet.

bash challenge: rename files from a list.

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

    bash challenge: rename files from a list.

    I've ripped a DVD set into episodes and acquired all the subtitles in external files. My media server - Plex - wants these filenames in these formats:

    Episode:
    X-Factor - s01e04 - Crazy People.mp4

    Subtitles:
    X-Factor - s01e04 - Crazy People.en.srt

    However, the downloaded srt files did not have the Episode name in the filename, just the Season/Episode numbers. I got the filenames this far using Krename:

    X-Factor - s01e04 - .srt

    Now I need to "read" the episode name from the filename of the mp4 and insert it along with .en in between the end of the filename and the extension.

    This task is compounded by the spaces everywhere, and it's 8 seasons of up to 12 episodes each. Not a manual task I want to do.

    I could work from the filenames in the directories or from a text file with the episodes in it.

    I'm trying to figure this out, but I'm not having any epiphanies.

    I sense I should be able to match the s01e04 labels somehow to indicate which episode title to grab. This would be SOOOO easy in postgresql...
    Last edited by oshunluvr; Mar 16, 2023, 07:05 AM.

    Please Read Me

    #2
    Well, this gets me the episode title from the filename, but it's not pretty:

    Code:
    #!/bin/bash
    shownum=(`for f in srt/*.srt; do echo "${f%%.*}" |awk '{print $5}' ; done`)
    
    for s in "${shownum[@]}"
    do
    b=`find . -name "*$s*" |grep mp4  |cut -c 40-`
    c=${b%.*}
    echo $c
    done
    ​
    I read the season/episode numbers from all the srt files, then found the matching mp4 file and isolated the episode title.

    It's a good start....

    Please Read Me

    Comment


      #3
      I'll bet you that Chat-GPT4 could write your bash script in 5 seconds! And, you could keep asking it to beautify it until you got it the way you wanted it.
      Amazing AI !!!
      "A nation that is afraid to let its people judge the truth and falsehood in an open market is a nation that is afraid of its people.”
      – John F. Kennedy, February 26, 1962.

      Comment


        #4
        You know GG, you are probably right but then I haven't learned anything new. You know when we stop learning we die. So not ready for that yet and neither are you!

        Please Read Me

        Comment


          #5
          With these bulk rename jobs I advise people to first generate a list of mv commands, so that one can check them. It's too easy to do things like renaming a bunch of files to the same name (thus discarding all but the last). I've done it, and seen others do it too often. The last time was a colleague only a month ago.

          IIUC the old and new names of the .srt file can be derived from the .mp4 file name. So, it's a matter of chopping up the .mp4 name and assembling the pieces. I tend to use bash (or zsh) constructs for string manipulation because it's faster than using other utilities like cut and sed as they're run in subprocesses. And, I only have to look at one or two pages of one manual (the bash one).

          If the spaces and dashes in the names are absolutely consistent, and there's otherwise no dashes in the file names or the episode names, how about (minimally tested)
          Code:
          #!/bin/bash
          unalias ls 2>/dev/null
          ls "$@" |
          while read line;do
              piece1="${line%-*}" 
              piece2="${line#*-}"
              piece3="${piece2#*-}"
              piece4="${piece3%.mp4}"
              echo "mv '$piece1- .srt' '$piece1-$piece4.en.srt'"
          done
          One would run that on *.mp4 in a directory saving the output to a file, and checking it. Then, one sources the file. One could run it on several directories if convenient, or **/*.mp4 to hit a whole hierarchy.

          (If I was doing this I'd likely start with a listing of the files, then use editor (vim) commands to transform the lines into the required move commands. But that's really hard to post about on a forum, even though it's similarly piece-wise.)
          Last edited by jlittle; Mar 15, 2023, 11:33 PM.
          Regards, John Little

          Comment


            #6
            This did the job:
            Code:
            #!/bin/bash
            shownum=(`for f in srt/*.srt; do echo "${f%%.*}" |awk '{print $5}' ; done`)
            
            for s in "${shownum[@]}"
            do
            b=`find . -name "*$s*" |grep mp4  |cut -c 40-`
            d=`find . -name "*$s*" |grep srt`
            c=${b%.*}
            e="${d%.*}"$c".en.srt"
            
            mv -v "${d}" "${e}"
            
            done​
            As I suspected I had a hard time with the spaces everywhere. I'm sure two or three of those lines could be combined, but the job is done so I'm satisfied.

            Please Read Me

            Comment


              #7
              Thanks Jlittle, I didn't see you post until after I posted my last. I had a hard time trying to get the commands that made $e in the mv command, so I just added the extra variable.

              One thing I had going for me was the previous filenames of the srt files was a consistent length. So trimming all but the s01e04 part gave me a solid search criteria. Looking back, I probably didn't need to do that because I could have just searched for the whole name. My idea was to avoid the spaces in that part at least.

              Please Read Me

              Comment


                #8
                I also see I could have used the script to move the files to the target folders. I wasn't thinking about that as a difficult part of the task, but it would have made the script more funtional.

                Curious about the "unalias" part in your script?

                Please Read Me

                Comment


                  #9
                  I guess the cyborg Mr. Little uses unalias to be certain of the output format of ls, because many distributions (and many people) have an alias for ls in their .bashrc, .bash_aliases or wherever… Probably the most commonly used alias.

                  Redirection 2> /dev/null for stderr if one doesn't have an alias for ls.
                  Last edited by Schwarzer Kater; Mar 16, 2023, 07:23 AM. Reason: tttypos, of course
                  Debian KDE & LXQt • Kubuntu & Lubuntu • openSUSE KDE • Windows • macOS X
                  Desktop: Lenovo ThinkCentre M75s • Laptop: Apple MacBook Pro 13" • and others

                  get rid of Snap script (20.04 +)reinstall Snap for release-upgrade script (20.04 +)
                  install traditional Firefox script (22.04 +)​ • install traditional Thunderbird script (24.04)

                  Comment

                  Working...
                  X