Python :仅将那些 .avi 文件从一个目录复制到另一个目录,这些文件在命令行参数中给定的文件名范围内

Python : Copy only those .avi files from one directory to another which are within a file name range given in command line argument

我有不同的目录,其中包含给定格式的 .avi 个文件:

2021-03-06
---17 15 33.avi
   17 16 33.avi
   17 17 33.avi

2021-03-07
---19 43 57.avi
   19 44 57.avi
   19 45 57.avi

Retrieval

用户将给出他想从中复制文件的目录名、起始文件名和结束文件名作为参数。示例:

python copy.py -f "2021-03-07" -s "19 43 57" -e "19 44 57"

在 运行 之后,应在 Retrieval 中创建一个新的子目录,该目录与起始文件名相同,其中应复制 .avi 文件。

预期结果:

2021-03-06
---17 15 33.avi
   17 16 33.avi
   17 17 33.avi

2021-03-07
---19 43 57.avi
   19 44 57.avi
   19 45 57.avi

Retrieval
---19 43 57
   ---19 43 57.avi
      19 44 57.avi

[注意:只应复制开始和结束文件名内的视频,包括给定的文件名]

这是我到目前为止能够编写的脚本:

import os
import shutil
import glob
import argparse
from pprint import pprint 



ap = argparse.ArgumentParser()

ap.add_argument("-d","--startTime",  type=str, required=True,
                help="Start time of video")
ap.add_argument("-r","--endTime",  type=str, required=True,
                help="End time of video")
ap.add_argument("-f","--folder",  type=str, required=True,
                help="Folder name for which videos are to be merged")

args = ap.parse_args()

source='drive://'+args.folder+'//'
dest='drive://Retrieval//'+args.startTime+'//'
files = []
for dirname, dirnames, filenames in os.walk(source):
    # print path to all subdirectories first.
    for subdirname in dirnames:
        files.append(os.path.join(dirname, subdirname))

    # print path to all filenames.
    for filename in filenames:
        files.append(os.path.join(dirname, filename))
pprint(files)

if os.path.exists(dest):
    print("this folder exit in this dir")
else:
    dir = os.mkdir(dest)
    for f in files:
        shutil.copy(f,dest)
        print("done")

以上代码的问题是它将所有文件从源文件夹复制到目标文件夹。

要对文件执行模式搜索,您可以使用 glob. In example above for all operations with file paths I've used pathlib and there's Path.glob(),它提供 pathlibglob 之间的接口。

因此,要从文件夹中检索所有需要的文件,我们可以使用下一个模式:[0-9][0-9] [0-9][0-9] [0-9][0-9].avi。它将匹配所有 .avi 文件,其中名称将包含 3 个由 space.

分隔的 2 位数字

你的文件名包含时间,我建议你使用 time.strptime() or datetime.strptime() 来转换 startTime / endTime 参数和文件名进入相应的时间结构,我们将更容易比较。

我还为您的代码添加了一些基本的数据验证和消息,这是最终结果:

from argparse import ArgumentParser
from pathlib import Path
from time import strptime
from shutil import copy2

ap = ArgumentParser()

ap.add_argument("-s", "--startTime",  type=str, required=True,
                help="File name with Start time of video")
ap.add_argument("-e", "--endTime",  type=str, required=True,
                help="File name with End time of video")
ap.add_argument("-f", "--folder",  type=str, required=True,
                help="Folder name for which videos are to be merged")

args = ap.parse_args()

root_path = Path(r"drive://")
filename_format = "[0-9][0-9] [0-9][0-9] [0-9][0-9].avi"
time_format = "%H %M %S"

src_path = root_path / args.folder
dst_path = root_path / "Retrieval" / args.startTime

# source folder validation
if not src_path.is_dir():
    raise FileNotFoundError("Provided folder doesn't exist")
# destination folder vaidation
try:
    dst_path.mkdir(parents=True, exist_ok=True)
except OSError:
    raise ValueError("Can't create folder:", dst_path)
# start/end time validation
try:
    min_time = strptime(args.startTime, time_format)
    max_time = strptime(args.endTime, time_format)
except ValueError:
    raise ValueError("Invalid start/end time")

for file in src_path.glob(filename_format):
    try:
        parsed_time = strptime(file.stem, time_format)
    except ValueError:
        print("Skipped:", file)
    else:
        if min_time <= parsed_time <= max_time:
            copy2(file, dst_path / file.name)
            print("Copied:", file)
        else:
            print("Skipped:", file)