使用通配符复制文件,如果python脚本不存在则创建目录

时间:2017-04-11 00:19:27

标签: python

我正在尝试编写一个python脚本来节省我复制/粘贴更新文件的时间。

这是我到目前为止所得到的:

import os
import shutil

src_files = [
    'C:/orig/path/to/some/file/module_some_file.php',
    'C:/orig/path/to/some/other/file/module_some_file.php',
    'C:/orig/path/to/some/third/file/module_with_diff_name_after_module.php',
    # ....
]

dest_files = [
    'C:/copy/path/to/some/file/module_some_file.php',
    'C:/copy/path/to/some/other/file/module_some_file.php',
    'C:/orig/path/to/some/third/file/module_with_diff_name_after_module.php',
    # ....
]

for i in range(len(src_files)): 
  FILE_DIR=os.path.dirname(dest_files[i])
  if not os.path.exists(FILE_DIR):
    os.makedirs(FILE_DIR)
  if (os.path.isfile(src_files[i])):
    shutil.copy(src_files[i], dest_files[i])

这种方式有效,但我想实现我输入例如py copy.py module --src "C:/orig/path/to/some" --dest "C:/copy/path/to/some",脚本将搜索名称包含" module"的所有文件。一种通配符解决方案。 我的问题,我能用python实现我想要的吗?并且有人可以帮助我将列表替换为优雅的通配符/搜索解决方案吗?

环境:Windows / python 3.6.1

这是我的第一个python脚本,所以请有一些怜悯:))

3 个答案:

答案 0 :(得分:3)

到目前为止看起来你做得很好,但是你缺少的两个部分是(1)如何从命令行解析参数,以及(2)如何在Python中使用通配符。我将按顺序解决这些问题:

命令行参数

Python sys模块是一种简单的命令行参数入门方法。

假设我有一个名为test_args.py的文件:

# test_args.py
import sys

print(sys.argv)

如果我在命令行输入python test_argv.py arg1 arg2 arg3,它会打印出所用参数的列表:

# ['test_args.py', 'arg1', 'arg2', 'arg3']

有关更高级的arg解析,请参阅argparse文档: https://docs.python.org/3.3/library/argparse.html

通配符

Python的内置glob模块应该能够实现您正在寻找的内容。这很简单。如果我的目录被调用" myfolder"并有这种结构:

myfolder
.
├── data1.csv
├── data2.csv
├── file1.txt
├── file2.txt
└── file3.txt

这是Python为我提供的内容:

import glob

pattern1 = '*.txt'
matching_filenames_1 = glob.glob(pattern1)
print(matching_filenames_1)
# ['file1.txt', 'file2.txt', 'file3.txt']

pattern2 = '*2*'
matching_filenames_2 = glob.glob(pattern2)
print(matching_filenames_2)
# ['data2.csv', 'file2.txt']

Argparse

正如我上面所说,argparse模块为您提供了大量开箱即用的功能。看看:

import argparse
import shutil
import sys

def parse_args():
    # Set up the parser, and tell it what arguments to expect
    parser = argparse.ArgumentParser()
    parser.add_argument('--src', nargs='*')
    parser.add_argument('--dest')
    # Get the list of arguments from the command line, starting from
    # index 1 (since index 0 is the name of this file).
    raw_args = sys.argv[1:]
    # Parse the args, and return the object containing them
    args = parser.parse_args(raw_args)
    return args

def copy_files():
    # Use our custom function to parse the arguments
    args = parse_args()
    source_files = args.src
    destination_folder = args.dest
    # Copy each file into the destination folder
    for file in source_files:
        shutil.copy(file, destination_folder)

copy_files()

答案 1 :(得分:1)

您可以使用glob搜索具有特定名称的所有文件。这是一个例子:

import shutil
import glob, sys, os

src_files = glob.glob1(sys.argv[3], '*%s*'%sys.argv[1])
dest = sys.argv[5]
for name in src_files:
    shutil.copy(os.path.join(sys.argv[3], name), os.path.join(dest, name))

py modulename.py module --src "C:/orig/path/to/some" --dest "C:/copy/path/to/some"

要改进此代码,可以使用argparse而不是sys.argv。

这是一种更专业的方式:

import shutil, argparse
import glob, os

parser = argparse.ArgumentParser()
parser.add_argument('name', metavar='N', type=str, nargs='+')
parser.add_argument('--src', required=False)
parser.add_argument('--dest',  required=False)
parsed = parser.parse_args()

src_files = glob.glob1(parsed.src, '*%s*'%parsed.name[0])
dest = parsed.dest
for name in src_files:
    shutil.copy(os.path.join(parsed.src, name), os.path.join(dest, name))

与所有其他命令调用一样,您在调用时需要使用=py modulename.py module --src="C:/orig/path/to/some" --dest="C:/copy/path/to/some"

答案 2 :(得分:0)

根据评论和答案,我已将脚本重写为以下内容:

import argparse, shutil, glob, sys, ntpath, os

def parse_args():
    # Set up the parser, and tell it what arguments to expect
    parser = argparse.ArgumentParser()
    parser.add_argument('--search')
    parser.add_argument('--src')
    parser.add_argument('--dest')
    # Get the list of arguments from the command line, starting from
    # index 1 (since index 0 is the name of this file).
    raw_args = sys.argv[1:]
    # Parse the args, and return the object containing them
    args = parser.parse_args(raw_args)
    return args

args = parse_args()

for filename in glob.iglob(args.src+'/**/*'+args.search+'*', recursive=True):
    src_file = os.path.join(args.src, filename)
    dest_file = filename.replace(args.src,args.dest)
    dest_dir = os.path.dirname(dest_file)
    if os.path.isdir(src_file):
        continue
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)
    if (os.path.isfile(src_file)):
        shutil.copy(src_file, dest_file)

现在我可以这样做:

py copy_files.py --search "searchterm" --src "C:/orig/path/to/some" --dest "C:/copy/path/to/some"

编辑abccd之后,我想我仍然可以改进这些界限:

for filename in glob.iglob(args.src+'/**/*'+args.search+'*', recursive=True):
    src_file = os.path.join(args.src, filename)
    dest_file = filename.replace(args.src,args.dest)
    dest_dir = os.path.dirname(dest_file)