Python - Create Folder From Filename, Move File into Created Folder - python

I am trying to do my own sort of Files2Folder in python, as it would be a lot more automated for my needs. I have it so that it creates a folder from the filename, but anytime I try to move the file into the newly created folder, I am returned an error. Any ideas?
import os
import os.path
import shutil
from pathlib import Path
import glob
rootdir = r'T:\rcloneFolder'
keepExt = ('.mkv', '.mp4', '.avi')
searchPath = Path(rootdir)
for file in searchPath.rglob("*"):
if file.name.endswith(keepExt):
print(file)
newName = (os.path.splitext(file.name)[0])
newFolders = os.mkdir(os.path.join(searchPath,newName))
print("Made File Directory: " + newName)
name = newName + '.mkv'
shutil.move(file, os.path.join(rootdir, name))

I think what you are looking for is that you need to use rootdir instead of searchPath to os.path.join since join expects a plain string, then the new filename is going to be os.path.join(rootdir, newName, newName) + ".mkv" since you want to rename the extension and move it into the folder with the same name, so the following code I believe would do what you are looking for:
for file in searchPath.rglob("*"):
if file.name.endswith(keepExt):
print(file)
name = (os.path.splitext(file.name)[0])
newFolder = os.path.join(rootdir,name)
os.mkdir(newFolder)
print("Made File Directory: " + newFolder)
destination = os.path.join(newFolder, name) + '.mkv'
shutil.move(file, destination)

from pathlib import Path
import glob, os
import shutil
for file in glob.glob('*.webm'):
folder_name = file.split('.')[0]
Path(folder_name).mkdir(parents=True, exist_ok=True)
shutil.move(file, folder_name)

Related

Python Script Saving/Copying into specific directory

I'm attempting to write a script that will save a file in the given directory, but I'm getting a NotADirecotryError[WinError 267] whenever I run it. Any ideas or tips on what I may have done incorrectly?
import shutil
import os
src = 'C:\\Users\\SpecificUsername\\Pictures\\test.txt\'
dest = 'C:\\Users\\SpecificUsername\\Desktop'
files = os.listdir(src)
for file in files:
shutil.copy(file, dest)
for file in files:
if os.path.isfile(file):
shutil.copy(file,dest) ```
There are a couple of things going on here:
You can just use forward slashes in the paths.
Your src is the test.txt file, and not a directory, so you cannot iterate over it using os.listdir().
You can also merge the two loops together since they are looping over the same set of data.
shutil.copy() takes a file path as input, while what you are passing is a filename.
The following code should work and it also copies directories as is:
import shutil
import os
basepath = "C:/Users/SpecificUsername/"
src = "Pictures/"
dest = "Desktop/"
files = os.listdir(os.path.join(basepath, src))
for filename in files:
filepath = os.path.join(basepath, src, filename)
if (os.path.isfile(filepath)):
print("File: " + filename)
shutil.copy(filepath,dest)
else:
print("Dir: " + filename)
shutil.copytree(filepath, os.path.join(dest, filename))
Hope it helps!

Why can't I copy .CR2 files using shutil?

import os
import shutil
os.chdir('C:\\')
dir_src = ('C:\\Users\\Tibi\\Desktop\\New Folder\\New Folder')
dir_dst = ('D:\\test')
for folder in os.walk(dir_src):
print(folder)
for filename in os.listdir(dir_src):
if filename.endswith('.CR2'):
shutil.copy(dir_src + filename, dir_dst)
print(filename)
Note that the file causing it to quit is one of the files I want to copy to the test folder. I tried using other file types and they don't work either.
output:
Traceback (most recent call last):
File "copyfiletree.py", line 14, in <module>
shutil.copy(dir_src + filename, dir_dst)
File "C:\Users\Tibi\Anaconda3\lib\shutil.py", line 235, in copy
copyfile(src, dst, follow_symlinks=follow_symlinks)
File "C:\Users\Tibi\Anaconda3\lib\shutil.py", line 114, in copyfile
with open(src, 'rb') as fsrc:
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\New FolderIMG_5221.CR2'
I think I should mention that my computer is infected with Spora ransomware (however, these files are not encrypted).
NEW CODE I'M TRYING TO USE:
import os
import shutil
#os.chdir('C:\\')
dir_src = ('D:\\Users\\Tibi\\Pictures')
dir_dst = ('D:\\test')
#while True:
# try:
# for folder in os.walk(dir_src):
# print(folder)
# for filename in os.listdir(dir_src):
# if filename.endswith('.CR2'):
# shutil.copy(dir_src + '\\' + filename, dir_dst)
# print(filename)
# except UnicodeEncodeError:
# print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>File %s was Skipped!<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" %filename)
import pathlib
import glob
dir_src = pathlib.Path(r'D:\\Users\\Tibi\\Pictures//Move')
dir_dst = pathlib.Path(r'D:\test')
for file in dir_src.rglob('*.mp4'):
shutil.copy(str(file), str(dir_dst / file.name))
print("Current File is: %s" % file)
In general, don't make paths using +. Use os.path.join which is smarter:
shutil.copy(os.path.join(dir_src, filename), dir_dst)
This will give you C:\...\folder\file instead of C:\...\folderfile.
Alternatively, you can use pathlib:
import pathlib
import shutil
dir_src = pathlib.Path(r'C:\Users\Tibi\Desktop\New Folder\New Folder')
dir_dst = pathlib.Path(r'D:\test')
for file in dir_src.rglob('*.CR2'):
shutil.copy(str(file), str(dir_dst / file.name))
If you need to match regardless of case, use this '*.[Cc][Rr]2' instead of '*.CR2'.
Add a path separator between to prevent C:\\New FolderIMG_5221.CR2 nonexistant file. Change this:
dir_src + filename
to this:
dir_src + '\\' + filename
or this for a more generic solution that might not be on Windows:
dir_src + os.path.sep + filename

How to change multiple filenames in a directory using Python

I am learning Python and I have been tasked with:
adding "file_" to the beginning of each name in a directory
changing the extension (directory contains 4 different types currently: .py, .TEXT, .rtf, .text)
I have many files, all with different names, each 7 characters long. I was able to change the extensions but it feels very clunky. I am positive there is a cleaner way to write the following (but its functioning, so no complaints on that note):
import os, sys
path = 'C:/Users/dana/Desktop/text_files_2/'
for filename in os.listdir(path):
if filename.endswith('.rtf'):
newname = filename.replace('.rtf', '.txt')
os.rename(filename, newname)
elif filename.endswith('.py'):
newname = filename.replace('.py', '.txt')
os.rename(filename, newname)
elif filename.endswith('.TEXT'):
newname = filename.replace('.TEXT', '.txt')
os.rename(filename, newname)
elif filename.endswith('.text'):
newname = filename.replace('.text', '.txt')
os.rename(filename, newname)
I do still have a bit of a problem:
the script currently must be inside my directory for it to run.
I can not figure out how to add "file_" to the start of each of the filenames [you would think that would be the easy part]. I have tried declaring newname as
newname = 'file_' + str(filename)
it then states filename is undefined.
Any assistance on my two existing issues would be greatly appreciated.
The basic idea would be first get the file extension part and the real file name part, then put the filename into a new string.
os.path.splitext(p) method will help to get the file extensions, for example: os.path.splitext('hello.world.aaa.txt') will return ['hello.world.aaa', '.txt'], it will ignore the leading dots.
So in this case, it can be done like this:
import os
import sys
path = 'C:/Users/dana/Desktop/text_files_2/'
for filename in os.listdir(path):
filename_splitext = os.path.splitext(filename)
if filename_splitext[1] in ['.rtf', '.py', '.TEXT', '.text']:
os.rename(os.path.join(path, filename),
os.path.join(path, 'file_' + filename_splitext[0] + '.txt'))
Supply the full path name with os.path.join():
os.rename(os.path.join(path, filename), os.path.join(name, newname))
and you can run your program from any directory.
You can further simply your program:
extensions = ['.rtf', '.py', '.TEXT', '.text']
for extension in extensions:
if filename.endswith(extension):
newname = filename.replace(extension, '.txt')
os.rename(os.path.join(path, filename), os.path.join(path, newname))
break
All the other elif statements are not needed anymore.
import glob, os
path = 'test/'# your path
extensions = ['.rtf', '.py', '.TEXT', '.text']
for file in glob.glob(os.path.join(path, '*.*')):
file_path, extension = os.path.splitext(file)
if extension in extensions:
new_file_name = '{0}.txt'.format(
os.path.basename(file_path)
)
if not new_file_name.startswith('file_'): # check if file allready has 'file_' at beginning
new_file_name = 'file_{0}'.format( # if not add
new_file_name
)
new_file = os.path.join(
os.path.dirname(file_path),
new_file_name
)
os.rename(file, new_file)
file_path, extension = os.path.splitext(file) getting file path without extension and extension f.e ('dir_name/file_name_without_extension','.extension')
os.path.dirname(file_path) getting directory f.e if file_path is dir1/dir2/file.ext result will be 'dir1/dir2'
os.path.basename(file_path) getting file name without extension
import os, sys
path = 'data' // Initial path
def changeFileName( path, oldExtensions, newExtension ):
for name in os.listdir(path):
for oldExtension in oldExtensions:
if name.endswith(oldExtension):
name = os.path.join(path, name)
newName = name.replace(oldExtension, newExtension)
os.rename(name, newName)
break;
if __name__ == "__main__":
changeFileName( 'data', ['.py', '.rtf' , '.text', '.TEXT'], '.txt')
Use an array to store all the old extensions and iterate through them.

Rename the files' names

I'd like to change the files whose extension are '.test.txt' into '.txt'.
As my codes as below, it cannot work cause invalid syntax happened to the place of 'if'.
Could you please figure out it?
Thank you so much.
import sys
import os
path = "Dir"
for(dirpath,dirnames,files)in os.walk(path):
for filename in files:
filepath = os.path.join(dirpath,filename)
if '.test.txt' in filename:
newfilename = filename.replace('.test.txt','.txt')
os.rename(filename,newfilename)
this should work...
import sys
import os
path = r"Dir"
for dirpath,dirnames,files in os.walk(path):
for filename in files:
filepath = os.path.join(dirpath,filename)
if '.test.txt' in filename:
newfilename = filename.replace('.test.txt','.txt')
newfilepath = os.path.join(dirpath, newfilename)
os.rename(filepath, newfilepath)
you did not define the new file path, in renaming action you have to supply the full file path, os.rename(src_path, dest_path)

Move child folder contents to parent folder in python

I have a specific problem in python. Below is my folder structure.
dstfolder/slave1/slave
I want the contents of 'slave' folder to be moved to 'slave1' (parent folder). Once moved,
'slave' folder should be deleted. shutil.move seems to be not helping.
Please let me know how to do it ?
Example using the os and shutil modules:
from os.path import join
from os import listdir, rmdir
from shutil import move
root = 'dstfolder/slave1'
for filename in listdir(join(root, 'slave')):
move(join(root, 'slave', filename), join(root, filename))
rmdir(join(root, 'slave'))
I needed something a little more generic, i.e. move all the files from all the [sub]+folders into the root folder.
For example start with:
root_folder
|----test1.txt
|----1
|----test2.txt
|----2
|----test3.txt
And end up with:
root_folder
|----test1.txt
|----test2.txt
|----test3.txt
A quick recursive function does the trick:
import os, shutil, sys
def move_to_root_folder(root_path, cur_path):
for filename in os.listdir(cur_path):
if os.path.isfile(os.path.join(cur_path, filename)):
shutil.move(os.path.join(cur_path, filename), os.path.join(root_path, filename))
elif os.path.isdir(os.path.join(cur_path, filename)):
move_to_root_folder(root_path, os.path.join(cur_path, filename))
else:
sys.exit("Should never reach here.")
# remove empty folders
if cur_path != root_path:
os.rmdir(cur_path)
You will usually call it with the same argument for root_path and cur_path, e.g. move_to_root_folder(os.getcwd(),os.getcwd()) if you want to try it in the python environment.
The problem might be with the path you specified in the shutil.move function
Try this code
import os
import shutil
for r,d,f in os.walk("slave1"):
for files in f:
filepath = os.path.join(os.getcwd(),"slave1","slave", files)
destpath = os.path.join(os.getcwd(),"slave1")
shutil.copy(filepath,destpath)
shutil.rmtree(os.path.join(os.getcwd(),"slave1","slave"))
Paste it into a .py file in the dstfolder. I.e. slave1 and this file should remain side by side. and then run it. worked for me
Use this if the files have same names, new file names will have folder names joined by '_'
import shutil
import os
source = 'path to folder'
def recursive_copy(path):
for f in sorted(os.listdir(os.path.join(os.getcwd(), path))):
file = os.path.join(path, f)
if os.path.isfile(file):
temp = os.path.split(path)
f_name = '_'.join(temp)
file_name = f_name + '_' + f
shutil.move(file, file_name)
else:
recursive_copy(file)
recursive_copy(source)
Maybe you could get into the dictionary slave, and then
exec system('mv .........')
It will work won't it?

Categories

Resources