13

I have a bunch of media files like those below:

tvshow.s01e11]Bloodlines.avi
tvshow.s01e12]suffer.avi
tvshow.s01e13]NotMe.avi

I would like to rename them to

tvshow.s01e11.avi
tvshow.s01e12.avi
tvshow.s01e13.avi

I’ve tried using rename but evidently I’m not getting the syntax right because it fails.

  • If you ever want to do this in a gui, krename is lovely. It has all sorts of powerful options and shows you what it's going to do before it actually does it. You could even use it to test out patterns that you could use in bash later. – Joe Aug 30 '16 at 7:00
9

This will rename the files. You need the \w* to signify any number of alphanumeric characters.

rename 's/\]\w*//' *

Reference: http://www.troubleshooters.com/codecorn/littperl/perlreg.htm#UsingSimpleWildcards

14

In shell, one could do simply:

for x in *]*.avi ; do 
    mv -i "$x" "${x%]*.avi}.avi"
done

The shell can produce a list of the filenames with just a regular glob, and ${var%pattern} removes the (shortest) matching pattern from the end of the string in variable var. Since the final extension is always .avi, I just removed it with the pattern and added it back. With the quotes, this should work with file names containing spaces too, like Fancy Name for a Show.s01e01]Asdf.avi

  • @NoviceC the extglob pattern wasn't a bad idea. Actually, something like ${x/]*([^.])} should do, it removes a bracket and any number of non-dots. (though fails if there are other brackets or dots, since it's not locked to the end of the string) – ilkkachu Aug 28 '16 at 8:57
  • That's a good point. But I really just overcomplicated the issue when I should have went with ${x/]*.avi} and just added a .avi like you. But I was also unsatisfied with how spaces in the name would break (`find . -name '*]*.avi'`). I was happy to provide a limited standard unix command method, since rename isn't, but this blows mine out of the water. – Novice C Aug 28 '16 at 9:11
2

This is all kinds of impractical - the other answers are much faster and shorter - but...

You can use PowerShell! Microsoft open-sourced it recently and made it cross-platform. For downloads and installation instructions for your OS, see the "Get PowerShell" section.

Once you get it installed, you can use this brief script:

Get-ChildItem -File '*]*.avi' | ForEach-Object {
    Rename-Item $_ -NewName (($_.Name -Split ']')[0] + '.avi')
}

Basically, it goes through each object in the current directory that is a file matching *]*.avi, gets the part before the bracket, tacks .avi back onto it, and assigns that as the new name.

To run it directly from Bash, use this semi-golfed one-liner:

powershell -command $'gci -File \'*]*.avi\'|%{rename-item $_ -NewName (($_.Name -Split \']\')[0]+\'.avi\')}'

Quote escaping courtesy of this Stack Overflow answer.

(Tested in Bash on Ubuntu on Windows. There's probably a much shorter way of doing it with PowerShell, but I wanted to show something that's comprehensible to people who don't know regular expressions.)

  • Rube Goldberg would be proud! Regexes are a real PITA to learn, but they're worth it many times over - even at the rudimentary level I'm able to use them at. – Joe Aug 30 '16 at 7:06
1

Debian has a package called mmv which might also be available in other distros, and should be easy enough to compile from source if not. It allows you to write this:

mmv '*]*.avi' '#1.avi'

You can read the Ubuntu man page for this command for more details.

0

This will search for the pattern and replace the text using sed.

 $sed 's/\(.*]\)[a-zA-z0-9].*\(.avi\)/\1\2/' filename

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.