Everything I am finding online is failing at this. Im using unbuntu 2204 and trying to write a bash script to replace the periods in my media library directory names. The newest script I found was 4 years old and I KNOW things have changed since then. I still tried it and it failed giving me an error of invalid syntax on line 2 at the do command.

All I need is to is this: I have a Kids movie directory and my movie directory. Both have over 400 movies in them, and some have details like audio type and resolution in the title. I careless about that since my plex library shows me this, I just want the movie title and the year in parentheses. ie Avatar (2019) instead of Avatar.2019.4k.DTS.xyz.

I finally got my download handler to rename directories properly on download, but I wanted to go back and rename the current library to this format also. Any help is appreciated!

UPDATE Sorry for the vagueness before and I appreciate the help in this endeavor. I DO NOT know scripting or any kind of language other than general linux commands. I have been dabbling in ubuntu mostly since 2013.

Link to the 4 year old script Replacing all the dots in the name of directories and sub directories recursively with spaces

My media is stored on a NAS, mounted at boot, and found in the following directories: /home/plex/MediaShare/Kids_Movies/* and /home/plex/MediaShare/My_Movies/*

The current directory names are like this Kung.Fu.Panda.3.2016.1080p.BluRay.DDP.5.1.H.265.-iVy

while the desired directory name is Kung Fu Panda 3 (2016)

I have tried the ZSH commands that was recommended, but zmv is not recognized. The latest shell is 5.8.1 and is my default shell. I would also accept Kung.Fu.Panda.3.2016 as directory name, but I cannot predict the format extension that are in my directory names as it now.

  • 1
    Better give a list of files with expected modified names. Are all of the videos the same format like Avatar.2019.4k.DTS.xyz ? Commented Mar 24 at 2:51
  • 4
    Oh, a script from 2020 for replacing periods in file names is going to be garbage. The whole periods-in-filenames branch of computer science has marched on to entirely new paradigms, not to mention all the shells and scripting languages.
    – Kaz
    Commented Mar 24 at 6:10
  • 2
    Vaguely interested in what your 2020 script choked on (and where it came from), but if the two solutions already posted are sufficient, go with one of them. I still use scripts I wrote in the 1990s, but they still work because they don't want to upset an old friend. Commented Mar 24 at 9:35
  • 1
    "it failed giving me an error of invalid syntax on line 2 at the do command" - can you post the script and tell us how you executed it. What shell do you use? (I'm wondering if you're using tcsh and you tried to source a sh script.) Commented Mar 25 at 9:49
  • Thanks for everyone's help on this. Sorry for the vagueness as I was more flustered and tired when I finally posted that I didnt realize my vagueness. I updated the post for some clarifications. Commented Mar 26 at 23:27

3 Answers 3


With zsh instead of bash:

autoload zmv
cd ~/Videos &&
  zmv -n '(**/)(*).(<1878-2024>).*(#q/)' '$1$2 ($3)'

Remove the -n (dry-run) if happy with the result.

Basically, it finds the (right-most if there's more than one) number between 1878 (for The Horse in Motion often considered the first movie ever made in 1878) and 2024 (this year as of writing, though you could replace with ${(%):-"%D{%Y}"} or "$(date +%Y)" outside of the single quotes for that to be computed dynamically) surrounded by dots in the base name of the directory ((#q/) in the pattern restricts the match to files of type directory) with the same surrounded with parenthesis and following what precedes that number.

If you wanted to replace dots with spaces in, and capitalize what precedes the year, and canonicalise the number, for instance to have some.path/to/the.HORSE.in.motion.00001878.foo.bar replaced with some.path/to/The Horse In Motion (1878), you could change that to:

zmv -n '(**/)(*).(<1878-2024>).*(#q/)' '$1${(C)2//./ } ($(($3)))'

Using Perl's rename, I recommend:

rename -n 's/\.(\d{4})\.4k\.DTS/($1)/' Avatar.2019.4k.DTS.xyz

remove -n when happy with the output.


You can use awk to pick just what you want from the filename. Consider this command:

$ echo "Avatar.2019.4k.DTS.xyz" | awk -F. '{print $1"("$2")"}'

Replace echo command by the full list of your files, pipe them to awk and apply mv or cp command. You can do it with a very short script.

  • When I tried this, I get a syntax error for bash: -bash: syntax error near unexpected token `(' Commented Mar 27 at 0:30
  • Tried on its own or inside a script? If the latter then I would need to see the script to comment.
    – dhm
    Commented Mar 27 at 8:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .