0

Rename subtitles with movie names from movie_name list to subtitles_list

import os

os.chdir("C:/Users/PC/Desktop/movies")

movies = []
for movie in os.listdir():
    movie_name,ext = os.path.splitext(movie)
    movies.append(movie_name)
    print(movie_name)

subs = []
for sub in os.listdir("C:/Users/PC/Desktop/subs"):
    sub_name, ext = os.path.splitext(sub)
    subs.append(sub_name)
    print(sub_name)
    
for movie,sub in zip(movies,subs):
    os.rename(sub,movie+".srt")

.........THE ERROR IS SHOWN AS GIVEN BELOW...............

movie_1
movie_2
movie_3
movie_4
A
B
C
D
Traceback (most recent call last):
  File "C:\Users\PC\Desktop\ABCD.PY", line 19, in <module>
    os.rename(sub,movie+".srt")
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'A' -> 'movie_1.srt'

How to tackle this error? Thank you.

EvensF
  • 1,479
  • 1
  • 10
  • 17
Damodarji
  • 93
  • 1
  • 5

2 Answers2

0

The problem is that you don't include the full path to the subtitle file in your rename call!

You could simply use f"{path}/{sub}" for this example, though Pathlib will be much more robust

subs_path = "C:/Users/PC/Desktop/subs"
...
for name_movie, name_sub in zip(movies, subs):
    path_sub = pathlib.Path(subs_path, name_sub)
    os.rename(path_sub, name_movie + ".srt")

Also, as renaming is rather dangerous, consider copying (this is slower, but often subtitle files are quite small) and also some advanced logic

  • collect all the actions before doing them
  • display what will happen
  • ask for confirmation
  • report each operation
  • allow skip/continue

Finally, just testing the lengths of the collections may go some ways to protecting you from improper removal (if they're unequal, you know something is wrong) as zip will not protect you with an Exception as you may expect

>>> list(zip([1,2], [3,4,5]))
[(1, 3), (2, 4)]
>>> list(zip([1,2,6], [3,4]))
[(1, 3), (2, 4)]

.. but you may also find that you have and want to retain more than one subtitle file, and so considering what to do, and perhaps fuzzy matching for nonexact names might make your life easier.

ti7
  • 16,375
  • 6
  • 40
  • 68
0

There are some information missing from your description to be able to help you. But I could guess and give you an answer

There may be a few things causing you that error:

  • In your code, you are not in the right directory when you try to rename those files:
    1. You first change the working directory to C:\Users\PC\Desktop\movies (os.chdir("C:/Users/PC/Desktop/movies"))
    2. You list the files in C:\Users\PC\Desktop\subs (os.listdir("C:/Users/PC/Desktop/subs"))
    3. You try rename those files from that list but your working directory is still C:\Users\PC\Desktop\movies
  • Unless the files in C:\Users\PC\Desktop\subs don't have an extension, when you try to rename them. you use only their name without their extension. So there a good chance they don't exist.

To fix this I would suggest you work with absolute paths instead of only filenames.

I would also suggest that you copy the files instead of renaming them. That way if it isn't exactly what you want, your original files are still there. It the outcome is what you expected, it's trivial to delete your original files afterwards. And for that, it is easier to use shutil.copy()

Here's what you can do to fix the situation with minimal modifications:

import os, os.path
import shutil

source_path = {
    'movies' : r"C:\Users\PC\Desktop\movies",
    'subtitles' : r"C:\Users\PC\Desktop\subs"
}
destination_path = r"C:\Users\PC\Desktop\movies"

movies = []
for movie in os.listdir(source_path['movies']):
    movie_name,ext = os.path.splitext(movie)
    movie_path = os.path.join(destination_path, movie_name)
    movies.append(movie_path)
    print(movie_path)

subs = []
for sub in os.listdir(source_path['subtitles']):
    sub_path = os.path.join(source_path['subtitles'], sub)
    subs.append(sub_path)
    print(sub_path)
    
for movie, sub in zip(movies, subs):
    shutil.copy(sub, movie + ".srt")

So this version:

  • Doesn't change the working directory
  • Uses os.path.join() to get a full path for each of these files
  • Uses raw strings so that a backslash doesn't have a special meaning. You can then easily paste a path copied from the File explorer, for example.

But you could further:

  • You could use list comprehensions to create your list of movie titles instead of using loops and .append().
  • You could use the features provided by the pathlib module

It would simplify your code. It would look like:

import pathlib
import shutil

source_path = {
    'movies' : pathlib.Path(r"C:\Users\PC\Desktop\movies"),
    'subtitles' : pathlib.Path(r"C:\Users\PC\Desktop\subs")
}
destination_path = pathlib.Path(r"C:\Users\PC\Desktop\movies")

movies = [
    destination_path / current_path.with_suffix('.srt').name
    for current_path in source_path['movies'].iterdir()
]
print('\n'.join(str(current_movie) for current_movie in movies))

subs = list(source_path['subtitles'].iterdir())
print('\n'.join(str(current_sub) for current_sub in subs))

for movie, sub in zip(movies, subs):
    shutil.copy(sub, movie)
Dharman
  • 30,962
  • 25
  • 85
  • 135
EvensF
  • 1,479
  • 1
  • 10
  • 17