0

I am trying to work on copying files to a different directory based on a specific file name listed in excel. I am using shutil to copy files from one directory to another directory, but it keep showing the FileNotFound.

This is the error message:
Traceback (most recent call last):
  File "C:\Python\HellWorld\TestCopyPaste.py", line 20, in <module>
    shutil.copytree(i, output_file, dirs_exist_ok=True)
  File "C:\Users\Asus\Anaconda3\envs\untitled\lib\shutil.py", line 556, in copytree
    with os.scandir(src) as itr:
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'Test.pdf'

I am still new to python, please let me know if there's any part can be enhanced :)

Below are my codes:

import os
import shutil
import pandas as pd

#Set file path
input_file = "C:\\Users\\Asus\\Desktop\\Python\\Input\\"
output_file = "C:\\Users\\Asus\\Desktop\\Python\\Output\\"

#Set new variable for the file path to store the list of files
file_list = os.listdir(input_file)

#search the required file name that need to copy to another location
#Create loop to search the files
condition = pd.read_excel(r'C:\\Users\\Asus\\Desktop\\Python\Condition.xlsx')

for i in file_list:
    for filename in condition:
        if filename in i:
            print(i)
            shutil.copytree(i, output_file, dirs_exist_ok=True)
mayliew
  • 35
  • 6
  • you probably need to add the folder's path as a prefix to the filename. – Gábor Fekete Nov 16 '22 at 16:22
  • i tried to do so, but it comes out another error /.\ NotADirectoryError: [WinError 267] The directory name is invalid: 'C:/Users/Asus/Desktop/Python/Input/Test.pdf' – mayliew Nov 16 '22 at 16:35
  • shutil.copytree(os.path.join(input_file, i), output_file, dirs_exist_ok=True) --> tis is the code after joining the file path to the filename – mayliew Nov 16 '22 at 16:36
  • try `filename` instead of `i` – Gábor Fekete Nov 16 '22 at 16:38
  • i tried but it turns out to error below where the path cant find, FileNotFoundError: [WinError 3] The system cannot find the path specified: 'C://Users//Asus//Desktop//Python//Input//Test' – mayliew Nov 16 '22 at 16:50

1 Answers1

0

As mentioned in comments one issue is that you aren't joining the filename to the full filepath ("input_file"). I'm not really familiar with shutil but I believe the function you want to use is shutil.copy not shutil.copytree. It looks like copytree copies the directory structure of a specified source directory and you are specifically only looking at a list of files within a top level directory. Another issue is how you are reading the excel file.

Assuming the files are listed in a single column it should be something like:

condition = pd.read_excel("C:\\Users\\Asus\\Desktop\\Python\\Condition.xlsx",index_col=None,header=None)

(I also removed your 'r' prefix to the string in this part)

Then to get the items in the first column: condition[0].tolist()

I also believe the second for loop is unnecessary. You can use the same if statement you already have in a single loop.

The following is my solution, just change he paths to what you want. I changed variable names to make it a little more readable as well.

(assumes all files are listed in a single column in excel with no header. And all file are in the input file directory with no subdirectories)

import os
import shutil
import pandas as pd

#Set file path
input_file_dir = "C:\\Users\\myusername\\py\\input\\"
output_file_dir = "C:\\Users\\myusername\\py\\output\\"

#Set new variable for the file path to store the list of files
file_list_from_dir = os.listdir(input_file_dir)

#search the required file name that need to copy to another location
#Create loop to search the files
file_list_from_excel = pd.read_excel("C:\\Users\\myusername\\py\\Condition.xlsx",index_col=None,header=None)

file_list_from_excel = file_list_from_excel[0].tolist()

for thefileNameinDir in file_list_from_dir: 
    if thefileNameinDir in file_list_from_excel:
        print(f"File matched: {thefileNameinDir}")
        tempSourcePath = os.path.join(input_file_dir,thefileNameinDir)
        shutil.copy(tempSourcePath, output_file_dir)
kconsiglio
  • 401
  • 1
  • 8
  • thank you so much @kconsiglio ! it really solved my problem. May I know how should I set it not taking exact match but partial match to the file list from excel? – mayliew Nov 18 '22 at 03:29
  • @yianlam glad I could help! It depends on what you mean by partial match. Like if two files start with the same substring like "test" and "test1" or if two files have the same substring "test" and "atestfile". If it's the latter change the if statement to `if any(s in thefileNameinDir for s in file_list_from_excel[0].tolist()):` if you only want to match them if they start with the same `if any(s.startswith(thefileNameinDir) for s in file_list_from_excel[0].tolist()):` [For reference](https://stackoverflow.com/questions/64127075/how-to-retrieve-partial-matches-from-a-list-of-strings) – kconsiglio Nov 18 '22 at 16:17