提问人:Demions 提问时间:11/12/2023 最后编辑:Demions 更新时间:11/13/2023 访问量:82
Python 列表 - 删除一些列表条目 [已关闭]
Python list - removing some list entries [closed]
问:
我有一个目录,里面存储了多个配置文件,具有相同的命名逻辑。首先是备份日期,然后是设备名称。我想编写一个脚本,该脚本将遍历目录中的所有文件,并仅保留最早出现的备份文件。
脚本运行前的示例目录内容:
02-10-2023__Device1.tar
03-10-2023__Device2.tar
01-11-2023__Device1.tar
03-11-2023__Device2.tar
04-11-2023__Device1.tar
06-11-2023__Device2.tar
11-11-2023__Device2.tar
...
脚本运行后出现的结果:
02-10-2023__Device1.tar
03-10-2023__Device2.tar
01-11-2023__Device1.tar
03-11-2023__Device2.tar
脚本不应触及较旧的(10 月)备份,而应仅保留“最旧”的 11 月备份。在上面的例子中,只有两个设备,就我而言,有 100+ 个不同的设备。
我试图用它来填充目录内容列表。我使用日期时间来获取当前月份/年份数据。然后,我尝试使用 for 循环浏览列表并填充一个新列表,其中我只存储应使用 .我被困在尝试计算以某种方式结束的文件名的累积的步骤中。os.listdir
os.remove
我走在正确的轨道上还是有更简单的方法?
到目前为止的代码:
import os, datetime
today=datetime.date.today()
month=today.month
year=today.year
date=str(str(month) + "-" + str(year))
files=os.listdir()
erase=[]
for file in files:
if ????? and str(file[3:10]) == date:
erase.append(file)
os.remove(erase)
我只是不确定如何添加第一个 if 语句,该语句只会在现有文件已准备好的情况下添加文件。我确实尝试过使用“files.count(file[3:]) > 1”,但这不起作用。
答:
2赞
Sash Sinha
11/13/2023
#1
也许你可以考虑将脚本分解为更小的、更容易推理的函数:
import datetime
import os
import subprocess
from collections import defaultdict
def get_device_name(filename: str) -> str:
"""Extracts the device name from the filename.
Args:
filename: The filename to extract the device name from.
Returns:
str: The extracted device name.
"""
return filename.split("__")[1]
def group_files_by_device(files: list[str]) -> dict[str, list[str]]:
"""Groups files by device name.
Args:
files: List of file names.
Returns:
dict[str, list[str]]: Dictionary grouping filenames by device name.
"""
grouped_files = defaultdict(list)
for file in files:
device_name = get_device_name(file)
grouped_files[device_name].append(file)
return grouped_files
def delete_newer_files(files: list[str], current_month: int,
current_year: int) -> None:
"""Deletes newer files, keeping only the oldest file for the current month and year.
Args:
files: List of file names for a specific device.
current_month: Current month.
current_year: Current year.
"""
files_to_keep = []
for file in files:
file_date_str = file.split("__")[0]
file_date = datetime.datetime.strptime(file_date_str, "%d-%m-%Y").date()
if file_date.month == current_month and file_date.year == current_year:
files_to_keep.append(file)
oldest_file = min(
files_to_keep,
default="",
key=lambda x: datetime.datetime.strptime(x.split("__")[0], "%d-%m-%Y"))
for file in files_to_keep:
if file != oldest_file:
os.remove(file)
def main() -> None:
"""Main function to execute the script."""
print("Before:")
_print_tar_files()
today = datetime.date.today()
current_month = today.month
current_year = today.year
files = [file for file in os.listdir() if file.endswith('.tar')]
grouped_files = group_files_by_device(files)
for device_files in grouped_files.values():
delete_newer_files(device_files, current_month, current_year)
print("After:")
_print_tar_files()
def _print_tar_files() -> None:
tar_files = [file for file in os.listdir() if file.endswith('.tar')]
print('\n'.join(sorted(tar_files)))
def _create_files_for_demonstration_purposes() -> None:
file_names = [
"02-10-2023__Device1.tar", "03-10-2023__Device2.tar",
"01-11-2023__Device1.tar", "03-11-2023__Device2.tar",
"04-11-2023__Device1.tar", "06-11-2023__Device2.tar",
"11-11-2023__Device2.tar"
]
for file_name in file_names:
subprocess.run(['touch', file_name])
if __name__ == "__main__":
_create_files_for_demonstration_purposes()
main()
输出:
Before:
01-11-2023__Device1.tar
02-10-2023__Device1.tar
03-10-2023__Device2.tar
03-11-2023__Device2.tar
04-11-2023__Device1.tar
06-11-2023__Device2.tar
11-11-2023__Device2.tar
After:
01-11-2023__Device1.tar
02-10-2023__Device1.tar
03-10-2023__Device2.tar
03-11-2023__Device2.tar
评论
0赞
Demions
11/13/2023
它按应有的方式工作,结果符合预期。我将首先查看每个步骤(将花费 sime 时间;))。谢谢腰带!
评论