我正在尝试编写一个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脚本,所以请有一些怜悯:))
答案 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
模块为您提供了大量开箱即用的功能。看看:
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)