鱼C论坛

 找回密码
 立即注册
查看: 2152|回复: 6

[已解决]关于批量文件重命名的问题

[复制链接]
发表于 2023-5-14 17:30:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

代码不知道哪里有问题,改完名总是会少一位数
比如应该改成  张1233.txt  结果实际改成了 张123.txt

  1. import tkinter as tk
  2. from tkinter import filedialog
  3. import os
  4. from tkinter import messagebox

  5. # 创建窗口
  6. window = tk.Tk()

  7. # 设置窗口标题
  8. window.title("My Window")

  9. # 设置窗口大小
  10. window.geometry("520x500")

  11. # 计算居中位置
  12. screen_width = window.winfo_screenwidth()
  13. screen_height = window.winfo_screenheight()
  14. x = (screen_width - window.winfo_reqwidth()) / 2
  15. y = (screen_height - window.winfo_reqheight()) / 2
  16. # 设置窗口位置
  17. window.geometry("+%d+%d" % (x, y))


  18. # 创建顶部输入框
  19. top_entry = tk.Entry(window)
  20. top_entry.place(x=50, y=10, width=400,height=25)

  21. # 创建顶部按钮
  22. def choose_folder():
  23.     default_dir = os.getcwd()
  24.     folder_path = filedialog.askdirectory(initialdir=default_dir)
  25.     top_entry.delete(0, tk.END)
  26.     top_entry.insert(0, folder_path)

  27. top_button = tk.Button(window, text="选择目录", command=choose_folder)
  28. top_button.place(x=430, y=10)


  29. # 创建左侧多行输入框控件和滚动条
  30. left_text = tk.Text(window)
  31. left_text.place(x=10, y=120, anchor="w", width=480,height=150 )

  32. left_scrollbar = tk.Scrollbar(left_text)
  33. left_scrollbar.place(x=460, y=0, height=145)
  34. left_text.config(yscrollcommand=left_scrollbar.set, wrap="char")

  35. # 设置左侧多行输入框控件的大小
  36. left_text.config(width=30, height=10)

  37. left_scrollbar.config(command=left_text.yview)

  38. # 创建右侧多行输入框控件和滚动条
  39. #right_text.place(x=left_text.winfo_x() + left_text.winfo_width(), y=200, anchor="w")
  40. right_text = tk.Text(window)
  41. right_text.place(x=10, y=300, anchor="w", width=480,height=150)

  42. right_scrollbar = tk.Scrollbar(right_text )
  43. right_scrollbar.place(x=460, y=0, height=145)
  44. right_text.config(yscrollcommand=right_scrollbar.set, wrap="word")

  45. # 设置右侧多行输入框控件的大小
  46. right_text.config(width=30, height=10)

  47. right_scrollbar.config(command=right_text.yview)



  48. def rename_txt_files(folder_path, left_text, right_text):
  49.     lines = left_text.get("1.0", "end").split("\n")
  50.     for root, dirs, files in os.walk(folder_path):
  51.         for file in files:
  52.             if file.endswith(".txt") and any(line in file for line in lines):
  53.                 old_name = os.path.join(root, file)
  54.                 line_num = lines.index([line for line in lines if line in file][0])
  55.                 new_name = os.path.join(root, right_text.get(f"{line_num+1}.0", f"{line_num+1}.end-1c").strip() + ".txt")
  56.                 print(new_name)
  57.                 if os.path.exists(new_name):
  58.                     #messagebox.showwarning("警告", f"文件名 {new_name} 已存在!")
  59.                     print("警告", f"文件名 {new_name} 已存在!")
  60.                 else:
  61.                     try:
  62.                         os.rename(old_name, new_name)
  63.                     except Exception as e:
  64.                          print("错误", f"重命名文件 {old_name} 为 {new_name} 时出错:{e}")
  65.                         #messagebox.showerror("错误", f"重命名文件 {old_name} 为 {new_name} 时出错:{e}")


  66. # 创建输出按钮
  67. def output_lines():
  68.     folder_path = top_entry.get()
  69.     if not folder_path:
  70.         messagebox.showwarning("警告", "您还没有选择目录!")
  71.         return
  72.       
  73.     lines = left_text.get("1.0", "end").split("\n")
  74.     lines2 = right_text.get("1.0", "end").split("\n")
  75.     rename_txt_files(folder_path, left_text, right_text)
  76.     print(left_text)
  77.     print(right_text)


  78. #遍历文件夹

  79. output_button = tk.Button(window, text="输出每行内容", command=output_lines)
  80. output_button.place(x=210, y=390)

  81. # 运行窗口
  82. window.mainloop()
复制代码
最佳答案
2023-5-14 17:51:15
koma610630 发表于 2023-5-14 17:34
测试了 还是有问题, 重命名会少一位

对不起,我之前的解释可能有误,你在这里遇到的问题可能与获取新名称中的行号有关。你的代码在使用 "right_text.get(f"{line_num+1}.0", f"{line_num+1}.end-1c")" 时可能在某些情况下没有得到正确的结果,特别是当 right_text 中的行数少于 left_text 中的行数时。这可能导致你从 right_text 中获取的新文件名字符串比预期的短。

我认为可以更改代码以确保每次都能正确地从 right_text 中获取新文件名。以下是我对 rename_txt_files 函数的改动:

  1. def rename_txt_files(folder_path, left_text, right_text):
  2.     lines = left_text.get("1.0", "end").split("\n")
  3.     lines2 = right_text.get("1.0", "end").split("\n")
  4.     for root, dirs, files in os.walk(folder_path):
  5.         for file in files:
  6.             if file.endswith(".txt") and any(line in file for line in lines):
  7.                 old_name = os.path.join(root, file)
  8.                 line_num = lines.index([line for line in lines if line in file][0])
  9.                 if line_num < len(lines2):
  10.                     new_name = os.path.join(root, lines2[line_num].strip() + ".txt")
  11.                     print(new_name)
  12.                     if os.path.exists(new_name):
  13.                         print("警告", f"文件名 {new_name} 已存在!")
  14.                     else:
  15.                         try:
  16.                             os.rename(old_name, new_name)
  17.                         except Exception as e:
  18.                             print("错误", f"重命名文件 {old_name} 为 {new_name} 时出错:{e}")
  19.                 else:
  20.                     print("错误", f"在右侧文本框中找不到对应的新文件名")
复制代码


在这个改动中,我首先将 right_text 的所有行读入一个名为 lines2 的列表中。然后,每次获取新的文件名时,我会检查 line_num 是否小于 lines2 的长度。如果是,我会使用 lines2[line_num] 作为新的文件名。如果不是,我会打印一个错误消息。这样可以确保我们不会试图从 right_text 中获取一个不存在的行。

希望这个改动能帮助你解决问题。如果仍然存在问题,请告诉我,我会尽力帮助你解决。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-5-14 17:30:42 | 显示全部楼层
问题出在这一行代码:

line_num = lines.index([line for line in lines if line in file][0])

这里使用了列表推导式,但是如果有多个匹配的行,它只会返回第一个匹配的行,导致重命名时少了一位数。为了解决这个问题,我们可以使用一个循环来查找匹配的行,如下所示:

for line in lines:
    if line in file:
        line_num = lines.index(line)
        break

这样就可以找到所有匹配的行,并返回第一个匹配的行的索引值。完整代码如下:
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-14 17:31:12 | 显示全部楼层
isdkz 发表于 2023-5-14 17:30
问题出在这一行代码:

line_num = lines.index([line for line in lines if line in file][0])

完整的代码呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-14 17:34:40 | 显示全部楼层
isdkz 发表于 2023-5-14 17:30
问题出在这一行代码:

line_num = lines.index([line for line in lines if line in file][0])

测试了 还是有问题, 重命名会少一位
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-14 17:44:12 | 显示全部楼层
在 `rename_txt_files` 函数中,文件名的获取可能出现问题导致名称缺失一位数。具体来说,当文件名中包含多个数字时,函数会将最后一个作为后缀名并删除其他数字。这是因为在 `if file.endswith(".txt") and any(line in file for line in lines):` 这一行代码中,对于任意符合条件的文件名,仅取其中第一个匹配到的字符串作为需要替换的内容。

为了解决这一问题,请修改 `rename_txt_files` 函数中的以下代码:


  1. line_num = lines.index([line for line in lines if line in file][0])
  2. new_name = os.path.join(root, right_text.get(f"{line_num+1}.0", f"{line_num+1}.end-1c").strip() + ".txt")
复制代码

将其改为如下代码:


  1. for line in lines:
  2.     if line in file:
  3.         new_suffix = right_text.get(f"{lines.index(line)+1}.0", f"{lines.index(line)+1}.end-1c").strip()
  4.         break
  5. else:
  6.     return

  7. name_without_suffix, _ = os.path.splitext(file)
  8. new_name = os.path.join(root, name_without_suffix + new_suffix + ".txt")
复制代码


这里使用了一个 `for/else` 构造,在 `for` 循环中遍历所有需要替换的内容,找到第一个匹配文件名的字符串,并用它来得到新的后缀名。如果没有找到,则直接结束函数。得到新的后缀名之后,可以使用 `os.path.splitext` 函数来获取文件名和原来的后缀名,并拼接得到新的完整文件名。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-14 17:51:15 | 显示全部楼层    本楼为最佳答案   
koma610630 发表于 2023-5-14 17:34
测试了 还是有问题, 重命名会少一位

对不起,我之前的解释可能有误,你在这里遇到的问题可能与获取新名称中的行号有关。你的代码在使用 "right_text.get(f"{line_num+1}.0", f"{line_num+1}.end-1c")" 时可能在某些情况下没有得到正确的结果,特别是当 right_text 中的行数少于 left_text 中的行数时。这可能导致你从 right_text 中获取的新文件名字符串比预期的短。

我认为可以更改代码以确保每次都能正确地从 right_text 中获取新文件名。以下是我对 rename_txt_files 函数的改动:

  1. def rename_txt_files(folder_path, left_text, right_text):
  2.     lines = left_text.get("1.0", "end").split("\n")
  3.     lines2 = right_text.get("1.0", "end").split("\n")
  4.     for root, dirs, files in os.walk(folder_path):
  5.         for file in files:
  6.             if file.endswith(".txt") and any(line in file for line in lines):
  7.                 old_name = os.path.join(root, file)
  8.                 line_num = lines.index([line for line in lines if line in file][0])
  9.                 if line_num < len(lines2):
  10.                     new_name = os.path.join(root, lines2[line_num].strip() + ".txt")
  11.                     print(new_name)
  12.                     if os.path.exists(new_name):
  13.                         print("警告", f"文件名 {new_name} 已存在!")
  14.                     else:
  15.                         try:
  16.                             os.rename(old_name, new_name)
  17.                         except Exception as e:
  18.                             print("错误", f"重命名文件 {old_name} 为 {new_name} 时出错:{e}")
  19.                 else:
  20.                     print("错误", f"在右侧文本框中找不到对应的新文件名")
复制代码


在这个改动中,我首先将 right_text 的所有行读入一个名为 lines2 的列表中。然后,每次获取新的文件名时,我会检查 line_num 是否小于 lines2 的长度。如果是,我会使用 lines2[line_num] 作为新的文件名。如果不是,我会打印一个错误消息。这样可以确保我们不会试图从 right_text 中获取一个不存在的行。

希望这个改动能帮助你解决问题。如果仍然存在问题,请告诉我,我会尽力帮助你解决。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-14 17:51:48 | 显示全部楼层
sfqxx 发表于 2023-5-14 17:44
在 `rename_txt_files` 函数中,文件名的获取可能出现问题导致名称缺失一位数。具体来说,当文件名中包含多 ...

还是不行, 重命名还是会少一位。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-28 23:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表