How to move multiple files whith spaces in their names with python? - python

I want to move multiple files (only files not folders) from the directory source to directory dest. I'm doing like below using a for loop:
import os
import shutil
import glob
source = "r'" + "/This is/the source path/"
dest = "r'" + "/This is/the destination path/"
files = glob.glob(source+'/*.*')
for f in files:
shutil.move(source+f, dest)
>> IOError: [Errno 2] No such file or directory:
But if I do it for a single file like this, it works.
source = "/This is/the source path/"
dest = "/This is/the destination path/"
file_1 = r'This is a file.txt'
shutil.move(source+file_1, dest) ## This works
How can I dot for several files?

The portion of the path defined by source is going to be included in your file paths defined in files. Adding source to f in your loop would create redundancy. Instead try:
shutil.move(f, dest)
Also, I'm not sure why you are adding "r'". Perhaps you mean to define source as raw input such as when you defined file_1? In that case you should execute something like this:
source = r'/some/path/to/file.ext'

But how to print moved files name like if I use print("Moved:" ) will be next argument in print statement

Related

FileNotFoundError when trying to use os.rename

I've tried to write some code which will rename some files in a folder - essentially, they're listed as xxx_(a).bmp whereas they need to be xxx_a.bmp, where a runs from 1 to 2000.
I've used the inbuilt os.rename function to essentially swap them inside of a loop to get the right numbers, but this gives me FileNotFoundError [WinError2] the system cannot find the file specified Z:/AAA/BBB/xxx_(1).bmp' -> 'Z:/AAA/BBB/xxx_1.bmp'.
I've included the code I've written below if anyone could point me in the right direction. I've checked that I'm working in the right directory and it gives me the directory I'm expecting so I'm not sure why it can't find the files.
import os
n = 2000
folder = r"Z:/AAA/BBB/"
os.chdir(folder)
saved_path = os.getcwd()
print("CWD is" + saved_path)
for i in range(1,n):
old_file = os.path.join(folder, "xxx_(" + str(i) + ").bmp")
new_file = os.path.join(folder, "xxx_" +str(i)+ ".bmp")
os.rename(old_file, new_file)
print('renamed files')
The problem is os.rename doesn't create a new directory if the new name is a filename in a directory that does not currently exist.
In order to create the directory first, you can do the following in Python3:
os.makedirs(dirname, exist_ok=True)
In this case dirname can contain created or not-yet-created subdirectories.
As an alternative, one may use os.renames, which handles new and intermediate directories.
Try iterating files inside the directory and processing the files that meet your criteria.
from pathlib import Path
import re
folder = Path("Z:/AAA/BBB/")
for f in folder.iterdir():
if '(' in f.name:
new_name = f.stem.replace('(', '').replace(')', '')
# using regex
# new_name = re.sub('\(([^)]+)\)', r'\1', f.stem)
extension = f.suffix
new_path = f.with_name(new_name + extension)
f.rename(new_path)

Python: Looping through files in a different directory and scanning data

I am having a hard time looping through files in a directory that is different from the directory where the script was written. I also ideally would want my script through go to through all files that start with sasa. There are a couple of files in the folder such as sasa.1, sasa.2 etc... as well as other files such as doc1.pdf, doc2.pdf
I use Python Version 2.7 with windows Powershell
Locations of Everything
1) Python Script Location ex: C:Users\user\python_project
2) Main_Directory ex: C:Users\user\Desktop\Data
3) Current_Working_Directory ex: C:Users\user\python_project
Main directory contains 100 folders (folder A, B, C, D etc..)
Each of these folders contains many files including the sasa files of interest.
Attempts at running script
For 1 file the following works:
Script is run the following way: python script1.py
file_path = 'C:Users\user\Desktop\Data\A\sasa.1
def writing_function(file_path):
with open(file_path) as file_object:
lines = file_object.readlines()
for line in lines:
print(lines)
writing_function(file_path)
However, the following does not work
Script is run the following way: python script1.py A sasa.1
import os
import sys
from os.path import join
dr = sys.argv[1]
file_name = sys.argv[2]
file_path = 'C:Users\user\Desktop\Data'
new_file_path = os.path.join(file_path, dr)
new_file_path2 = os.path.join(new_file_path, file_name)
def writing_function(paths):
with open(paths) as file_object:
lines = file_object.readlines()
for line in lines:
print(line)
writing_function(new_file_path2)
I get the following error:
with open(paths) as file_object:
IO Error: [Errno 2] No such file or directory:
'C:Users\\user\\Desktop\\A\\sasa.1'
Please note right now I am just working on one file, I want to be able to loop through all of the sasa files in the folder.
It can be something in the line of:
import os
from os.path import join
def function_exec(file):
code to execute on each file
for root, dirs, files in os.walk('path/to/your/files'): # from your argv[1]
for f in files:
filename = join(root, f)
function_exec(filename)
Avoid using the variable dir. it is a python keyword. Try print(dir(os))
dir_ = argv[1] # is preferable
No one mentioned glob so far, so:
https://docs.python.org/3/library/glob.html
I think you can solve your problem using its ** magic:
If recursive is true, the pattern “**” will match any files and zero
or more directories and subdirectories. If the pattern is followed by
an os.sep, only directories and subdirectories match.
Also note you can change directory location using
os.chdir(path)

Python - Copying Multiple Files Within Directory

I am new to Python and attempting to write an automated testing program. More specifically, I am trying to copy several .xlsx files from one directory to another. I've researched pretty thoroughly and am partially there. My code is below, which does not return and errors, but does not accomplish what I am trying to do. I believe my code is not granular enough (I am getting stuck at the directory level). In a nutshell: File A contains c, d, e, f.1, f.2, f.3 (all Excel docs). File B is empty. I am trying to copy f.1, f.2, and f.3 into File B. I believe I need to add the startswith function at some point, too. Any help is appreciated. Thanks!
import os
import shutil
import glob
source = 'C:/Users/acars/Desktop/a'
dest1 = 'C:/Users/acars/Desktop/b'
src_files = os.listdir('C:/Users/acars/Desktop/a')
for file_name in src_files:
full_file_name = os.path.join('C:/Users/acars/Desktop/a','a') #'a' incorrect
if (os.path.isfile(full_file_name)):
shutil.copy(full_file_name, dest1)
else:
break
Use the variables source and dest1:
source = 'C:/Users/acars/Desktop/a'
dest1 = 'C:/Users/acars/Desktop/b'
src_files = os.listdir(source)
for file_name in src_files:
if not file_name.startswith('f'):
continue
src = os.path.join(source, file_name) # <--
dst = os.path.join(dest1, file_name) # <--
shutil.copy(src, dst)

How do i copy files with shutil in python

im trying to copy a .txt file from one dest to another. This code is running but the file isnt copying. What am i doing wrong?
import shutil
import os
src = "/c:/users/mick/temp"
src2 = "c:/users/mick"
dst = "/c:/users/mick/newfolder1/"
for files in src and src2:
if files.endswith(".txt"):
shutil.copy(files, dst)
Your for loop isn't actually searching through the files of each of your sources. In addition your for loop isn't looping through each of the sources but rather the letters in src and src2 that are present in both. This adjustment should handle what you need.
import os
src = ["c:/users/mick/temp", "c:/users/mick"]
dst = "c:/users/mick/newfolder1/"
for source in src:
for src_file in os.listdir(source):
if src_file.endswith(".txt"):
old_path = os.path.join(source, src_file)
new_path = os.path.join(dst, src_file)
os.rename(old_path, new_path)
You shouldn't need shutil for this situation as it is simply a more powerful os.rename that attempts to handle different scenarios a little better (to my knowledge). However if "newfolder1" isn't already existant than you will want to replace os.rename() with os.renames() as this attempts to create the directories inbetween.
shutils is useful for copying, but to move a file use
os.rename(oldpath, newpath)
I know the question is little older. But Here are the simple way to achieve your task. You may change the file extension as you wish. For copying you may use copy() & for moving yo may change it to move(). Hope this helps.
#To import the modules
import os
import shutil
#File path list atleast source & destination folders must be present not everything.
#*******************************WARNING**********************************************
#Make sure these folders names are already created while using the 'move() / copy()'*
#************************************************************************************
filePath1 = 'C:\\Users\\manimani\\Downloads' #Downloads folder
filePath2 = 'F:\\Projects\\Python\\Examples1' #Downloads folder
filePath3 = 'C:\\Users\\manimani\\python' #Python program files folder
filePath4 = 'F:\\Backup' #Backup folder
filePath5 = 'F:\\PDF_Downloads' #PDF files folder
filePath6 = 'C:\\Users\\manimani\\Videos' #Videos folder
filePath7 = 'F:\\WordFile_Downloads' #WordFiles folder
filePath8 = 'F:\\ExeFiles_Downloads' #ExeFiles folder
filePath9 = 'F:\\Image_Downloads' #JPEG_Files folder
#To change the directory from where the files to look // ***Source Directory***
os.chdir(filePath8)
#To get the list of files in the specific source directory
myFiles = os.listdir()
#To move all the '.docx' files to a different location // ***Destination Directory***
for filename in myFiles:
if filename.endswith('.docx'):
print('Moving the file : ' + filename)
shutil.move(filename, filePath4) #Destination directory name
print('All the files are moved as directed. Thanks')
import os, shutil
src1 = "c:/users/mick/temp/"
src2 = "c:/users/mick/"
dist = "c:/users/mick/newfolder"
if not os.path.isdir(dist) : os.mkdir(dist)
for src in [src1, src2] :
for f in os.listdir(src) :
if f.endswith(".txt") :
#print(src) # For testing purposes
shutil.copy(src, dist)
os.remove(src)
I think the error was that you were trying to copy a directory as a file, but you forgot to go through the files in the directory. You were just doing shutil.copy("c:/users/mick/temp/", c:/users/mick/newfolder/").

Copy a file into a directory with its original leading directories appended

I wonder if python provides a canonical way to copy a file to a directory with its original leading directories appended, like cp --parents does. From cp man page :
`--parents'
[...]
cp --parents a/b/c existing_dir
copies the file `a/b/c' to `existing_dir/a/b/c', creating any
missing intermediate directories.
I haven't seen anything in shutil documentation that refers to this. Of course, I could create the whole directory structure in existing_dir directory before copying any file to it, but it is perhaps overhead to do this.
I finally came up with the following code. It acts almost exactly as cp --parents does.
import os, shutil
def cp_parents(target_dir, files):
dirs = []
for file in files:
dirs.append(os.path.dirname(file))
dirs.sort(reverse=True)
for i in range(len(dirs)):
if not dirs[i] in dirs[i-1]:
need_dir = os.path.normpath(target_dir + dirs[i])
print("Creating", need_dir )
os.makedirs(need_dir)
for file in files:
dest = os.path.normpath(target_dir + file)
print("Copying %s to %s" % (file, dest))
shutil.copy(file, dest)
Call it like this:
target_dir = '/tmp/dummy'
files = [ '/tmp/dir/file1', '/tmp/dir/subdir/file2', '/tmp/file3' ]
cp_parents(target_dir, files)
Output is:
Creating /tmp/dummy/tmp/dir/subdir
Copying /tmp/dir/file1 to /tmp/dummy/tmp/dir/file1
Copying /tmp/dir/subdir/file2 to /tmp/dummy/tmp/dir/subdir/file2
Copying /tmp/file3 to /tmp/dummy/tmp/file3
There is probably a better way to handle this, but it works.
Not sure on your specific requirements, but sounds like shutil.copytree will be right for you. You can see the full docs here, but basically all you need to call in your example is something like
shutil.copytree( 'a/b/c', 'existing_dir/a/b/c' )
import os
import shutil
files = [ '/usr/bin/ls','/etc/passwd' , '/var/log/daily.out' , '/var/log/system.log' , '/var/log/asl/StoreData' ]
def copy_structure(dst_dir,source_files):
if not os.path.exists(dst_dir) and os.path.isdir(dst_dir):
os.mkdir(dst_dir)
for file in source_files:
dir_name = os.path.dirname(file)
final_dir_path = os.path.normpath(dst_dir+dir_name)
if not os.path.exists(final_dir_path):
os.makedirs(final_dir_path)
if os.path.exists(file):
shutil.copy(file,final_dir_path)
copy_structure('/tmp/backup',files)
ONLY 3.6 or higher (it uses f function)
This is my implementation of cp --parents
First gets the offsets for getting the src directories and the filename, also, for the directory offset (sometimes i wanted to omit the first folder of the src file)
Then it extracts the folders and the filename (the check in the src_dirs is because i noticed that when src file wasnt nested in any folder it crashed)
Finally it creates the directory tree into the destination folder and copies the file into it
def __copy_parents(src, dest_folder, dir_offset=0):
''' Copies src tree into dest, offset (optional) omits n folders of the src path'''
prev_offset = 0 if dir_offset == 0 else src.replace('/', '%', dir_offset - 1).find('/') + 1
post_offset = src.rfind('/')
src_dirs = '' if post_offset == -1 else src[prev_offset:post_offset]
src_filename = src[post_offset + 1:]
os.makedirs(f'{dest_folder}/{src_dirs}', exist_ok=True)
shutil.copy(src, f'{dest_folder}/{src_dirs}/{src_filename}')

Categories