将带有电影名称的字幕从 movie_name 列表重命名为 subtitles_list 而不使用正则表达式

Rename subtitles with movie names from movie_name list to subtitles_list without regex

将带有电影名称的字幕从 movie_name 列表重命名为 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")

.........错误如下所示......

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'

如何解决这个错误?谢谢。

问题是您没有在重命名调用中包含字幕文件的完整路径!

对于此示例,您可以简单地使用 f"{path}/{sub}",但 Pathlib 会更加稳健

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")

此外,由于重命名相当危险,请考虑复制(速度较慢,但​​字幕文件通常很小)以及一些高级逻辑

  • 在做之前收集所有的动作
  • 显示会发生什么
  • 请求确认
  • 报告每个操作
  • 允许skip/continue

最后,仅测试集合的长度可能会在某些方面保护您免受不当删除(如果它们不相等,您知道 某事 是错误的)因为 zip 不会像您期望的那样用异常保护您

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

.. 但您可能还会发现您拥有并希望保留多个字幕文件,因此考虑如何做,也许 fuzzy matching 不准确的名称可能会让您的生活更轻松。

您的描述中缺少一些信息,无法为您提供帮助。但我可以猜到并给你答案

可能有一些原因导致您出现该错误:

  • 在您的代码中,当您尝试重命名这些文件时,您不在正确的目录中:
    1. 您首先将工作目录更改为C:\Users\PC\Desktop\movies (os.chdir("C:/Users/PC/Desktop/movies"))
    2. 您列出 C:\Users\PC\Desktop\subs (os.listdir("C:/Users/PC/Desktop/subs"))
    3. 中的文件
    4. 您尝试重命名该列表中的那些文件,但您的工作目录仍然是 C:\Users\PC\Desktop\movies
  • 除非 C:\Users\PC\Desktop\subs 中的文件没有扩展名,否则当您尝试重命名它们时。您只使用他们的名字而不使用他们的扩展名。所以它们很可能不存在。

要解决此问题,我建议您使用绝对路径,而不仅仅是文件名。

我还建议您复制文件而不是重命名它们。这样,如果它不是您想要的,您的原始文件仍然存在。如果结果是您所期望的,之后删除您的原始文件是微不足道的。为此,使用 shutil.copy()

更容易

以下是您可以通过最少的修改来解决此问题的方法:

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")

所以这个版本:

  • 不改变工作目录
  • 使用 os.path.join() 获取每个文件的完整路径
  • 使用 raw strings 这样反斜杠就没有特殊含义了。例如,您随后可以轻松粘贴从文件资源管理器复制的路径。

但您可以进一步:

  • 您可以使用 list comprehensions 创建电影片名列表,而不是使用循环和 .append()
  • 您可以使用 pathlib 模块提供的功能

它会简化您的代码。它看起来像:

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)