[英]Copy files from one folder to another with matching names in .txt file
I want to copy files from one big folder to another folder based on matching file names in a .txt
file.我想根据
.txt
文件中的匹配文件名将文件从一个大文件夹复制到另一个文件夹。
My list.txt
file contains file names:我的
list.txt
文件包含文件名:
S001
S002
S003
and another big folder contains many files for ex.另一个大文件夹包含许多文件,例如。
S001, S002, S003, S004, S005
. S001, S002, S003, S004, S005
。
I only want to copy the files from this big folder that matches the file names in my list.txt
file.我只想从这个大文件夹中复制与我的
list.txt
文件中的文件名匹配的文件。
I have tried Bash, Python - not working.我试过 Bash、Python - 不工作。
for /f %%f in list.txt do robocopy SourceFolder/ DestinationFolder/ %%f
is not working either.也不工作。
My logic in Python is not working:我在 Python 中的逻辑不起作用:
import os
import shutil
def main():
destination = "DestinationFolder/copy"
source = "SourceFolder/MyBigData"
with open(source, "r") as lines:
filenames_to_copy = set(line.rstrip() for line in lines)
for filenames in os.walk(destination):
for filename in filenames:
if filename in filenames_to_copy:
shutil.copy(source, destination)
Any answers in Bash, Python or R?在 Bash、Python 或 R 中有任何答案吗?
Thanks谢谢
I think the issue with your Python code is that with os.walk()
your filename
will be a list everytime, which will not be found in your filenames_to_copy.我认为您的 Python 代码的问题在于,使用
os.walk()
您的filename
每次都会是一个列表,而不会在您的 filenames_to_copy 中找到。
I'd recommend trying with os.listdir()
instead as this will return a list of the names of filenames/folders as strings - easier to compare against your filenames_to_copy.我建议尝试使用
os.listdir()
代替,因为这会将文件名/文件夹的名称列表作为字符串返回 - 更容易与您的 filenames_to_copy 进行比较。
Other note - perhaps you want to do os.listdir()
(or os.walk()
) on the source instead of the destination.其他注意事项 - 也许您想在源而不是目标上执行
os.listdir()
(或os.walk()
)。 Currently, you're only copying files from the source to the destination if the file already exists in the destination.目前,如果文件已存在于目标中,则您仅将文件从源复制到目标。
os.walk()
will return a tuple of three elements: the name of the current directory inspected, the list of folders in it, and the list of files in it. os.walk()
将返回一个包含三个元素的元组:检查的当前目录的名称、其中的文件夹列表以及其中的文件列表。 You are only interested in the latter.你只对后者感兴趣。 So your should iterate with:
所以你应该迭代:
for _, _, filenames in os.walk(destination):
As pointed out by JezMonkey, os.listdir()
is easier to use as it will list of the files and folders in the requested directory.正如 JezMonkey 所指出的,
os.listdir()
更易于使用,因为它将列出请求目录中的文件和文件夹。 However, you will lose the recursive search that os.walk()
enables.但是,您将失去
os.walk()
启用的递归搜索。 If all your files are in the same folder and not hidden in some folders, you'd rather use os.listdir()
.如果您的所有文件都在同一个文件夹中并且没有隐藏在某些文件夹中,则您宁愿使用
os.listdir()
。
The second problem I see in you code is that you copy source
when I think you want to copy os.path.join(source, filename)
.我在你的代码中看到的第二个问题是,当我认为你想复制
os.path.join(source, filename)
时,你复制了source
代码。
Can you publish the exact error you have with the Python script so that we can better help you.您能否发布您在 Python 脚本中遇到的确切错误,以便我们更好地为您提供帮助。
UPDATE更新
You actually don't need to list all the files in the source folder.您实际上不需要列出源文件夹中的所有文件。 With
os.path.exists
you can check that the file exists and copy it if it does.使用
os.path.exists
您可以检查文件是否存在,如果存在则复制它。
import os
import shutil
def main():
destination = "DestinationFolder/copy"
source = "SourceFolder/MyBigData"
with open("list.txt", "r") as lines: # adapt the name of the file to open to your exact location.
filenames_to_copy = set(line.rstrip() for line in lines)
for filename in filenames_to_copy:
source_path = os.path.join(source, filename)
if os.path.exists(source_path):
print("copying {} to {}".format(source_path, destination))
shutil.copy(source_path, destination)
You can try with below code -您可以尝试使用以下代码 -
import glob
big_dir = "~\big_dir"
copy_to = "~\copy_to"
copy_ref = "~\copy_ref.txt"
big_dir_files = [os.path.basename(f) for f in glob.glob(os.path.join(big_dir, '*'))]
print 'big_dir', big_dir_files # Returns all filenames from big directory
with open(copy_ref, "r") as lines:
filenames_to_copy = set(line.rstrip() for line in lines)
print filenames_to_copy # prints filename which you have in .txt file
for file in filenames_to_copy:
if file in big_dir_files: # Matches filename from ref.txt with filename in big dir
file_to_copy = os.path.join(big_dir, file)
copy_(file_to_copy, copy_to)
def copy_(source_dir, dest_dir):
files = glob.iglob(os.path.join(source_dir, '*'))
for file in files:
dest = os.path.join(dest_dir, os.path.basename(os.path.dirname(file)))
if not os.path.exists(dir_name):
os.mkdir(dest)
shutil.copy2(file, dest)
Reference:参考:
https://docs.python.org/3/library/glob.html https://docs.python.org/3/library/glob.html
Thank you @PySaad and @Guillaume for your contributions, although my script is working now: I added:感谢@PySaad 和@Guillaume 的贡献,尽管我的脚本现在正在运行:我补充说:
if os.path.exists(copy_to):
shutil.rmtree(copy_to)
shutil.copytree(file_to_copy, copy_to)
to the script and its working like a charm :)到脚本和它的工作就像一个魅力:)
Thanks a lot for your help!非常感谢你的帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.