So I got a Directory Dir and in Dir there are three subdirectories with five Files each:
Dir/A/ one,two,three,four,five.txt
Dir/B/ one,two,three,four,five.txt
Dir/C/ one,two,three,four,five.txt
As you can see there are four Files without extension and one with the .txtextension
How do I rename all Files without extension in a recursive manner?
Currently I'm trying this, which works for a single Directory, but how could I catch all Files if I put this Script into Dir?
import os, sys
for filename in os.listdir(os.path.dirname(os.path.abspath(__file__))):
base_file, ext = os.path.splitext(filename)
if ext == "":
os.rename(filename, base_file + ".png")
Use os.walk if you want to perform recursive traversal.
for root, dirs, files in os.walk(os.path.dirname(os.path.abspath(__file__))):
for file in files:
base_path, ext = os.path.splitext(os.path.join(root, file))
if not ext:
os.rename(base_path, base_path + ".png")
os.walk will segregate your files into normal files and directories, so os.path.isdir is not needed.
import os
my_dir = os.getcwd()
for root, dirnames, fnames in os.walk(my_dir):
for fname in fnames:
if fname.count('.'): continue # don't process a file with an extension
os.rename(os.path.join(root, fname), os.path.join(root, "{}.png".format(fname)))
Related
-I tried the script below but the script is copying batch file names and pythonw.exe into the found_file.txt file and also it is not displaying anything in the found files folder. If anyone would look into it and help me out, I'd appreciate it.
The code is below.
import shutil
path = 'C:'
FileList = []
extension = '.pdf' and '.docx' and '.jpeg'
# Scanning For Files :-
with os.scandir(path) as DirList:
for root, dirs_list, files_list in os.walk(path):
for file_name in files_list:
if os.path.splitext(file_name)[-1] == extension:
file_name_path = os.path.join(root, file_name)
for files in DirList:
if files.is_file():
FileList.append(files.name)
# After that it iterates over the FileList and write names to text file
with open("found_file.txt", 'w') as ffile:
for fname in files_list:
ffile.write(fname)
#copies all files into a folder called found_files
newPath = shutil.copy('files_list', 'C:/Users/PacY/Downloads/found_files')
the immediate action would be this:
import shutil
path = 'C:'
FileList = []
extensions = ['.pdf', '.docx', '.jpeg']
# Scanning For Files :-
with os.scandir(path) as DirList:
for root, dirs_list, files_list in os.walk(path):
for file_name in files_list:
# this loops over each extensions and evaluates it
for extension in extensions:
if os.path.splitext(file_name)[-1] == extension:
file_name_path = os.path.join(root, file_name)
# break here so that if matching extension is found it stops checking
break
for files in DirList:
if files.is_file():
FileList.append(files.name)
# After that it iterates over the FileList and write names to text file
with open("found_file.txt", 'w') as ffile:
for fname in files_list:
ffile.write(fname)
#copies all files into a folder called found_files
newPath = shutil.copy('files_list', 'C:/Users/PacY/Downloads/found_files')
You should learn about this because those are the basics. also if the code does not work feel free to ask questions. also isn't there a specific function for this? (not that I would know)
Kind of new to python. But after searching and trying to unzip some folders, then rename them that don't have static names. For example the file is New_05222016. The #s are the date, and that always changes. I want it to be a unzipped folder that is labeled "New".
This is what i have so far. It will unzipp my file, but won't rename it.
import zipfile,fnmatch,os
rootPath = r"C:/Users/Bob/Desktop/Bill"
pattern = '*.zip'
New = 'New*'
for root, dirs, files in os.walk(rootPath):
for filename in fnmatch.filter(files, pattern):
print(os.path.join(root, filename))
zipfile.ZipFile(os.path.join(root, filename)).extractall(os.path.join(root, os.path.splitext(filename)[0]))
for root, dirs, files in os.walk(rootPath):
for filename in fnmatch.filter(dir,New):
os.rename(dir,'C:/Users/Bob/Desktop/Bill/New')
if tried other ways. Such as just os.rename and typing it out. But i'm at a loss of what to do.
os.rename() will work fine, just be sure to specify the full path.
I've modified your example using os.listdir() to store the name of the unzipped directory and then renamed it using os.rename(). I also used re to leave the name of the zipped file intact.
import zipfile,fnmatch,os, re
rootPath = r"C:\Users\Bob\Desktop\Bill"
pattern = '*.zip'
New = 'New*'
for root, dirs, files in os.walk(rootPath):
for filename in fnmatch.filter(files, pattern):
print(os.path.join(root, filename))
zipfile.ZipFile(os.path.join(root, filename)).extractall(os.path.join(root, os.path.splitext(filename)[0]))
for dirName in os.listdir(rootPath):
if not re.search("zip", dirName):
os.rename(os.path.join(rootPath, dirName), os.path.join(rootPath,"New"))
I hope this helps!
The loop is working but once I put the if statements in it only prints I am a dir
If the if statements are not there I am able to print the dirpath, dirname, filename to the console
I am trying to list all the file names in a directory and get the MD5 sum.
from os import walk
import hashlib
import os
path = "/home/Desktop/myfile"
for (dirpath, dirname, filename) in walk(path):
if os.path.isdir(dirpath):
print("I am a dir")
if os.path.isfile(dirpath):
print(filename, hashlib.md5(open(filename, 'rb').read()).digest())
You're only checking dirpath. What you have as dirname and filename are actually collections of directory names and files under dirpath. Taken from the python docs, and modified slightly, as their example removes the files:
import os
for root, dirs, files in os.walk(top):
for name in files:
print(os.path.join(root, name))
for name in dirs:
print(os.path.join(root, name))
Will print the list of of directories and files under top and then will recurse down the directories in under top and print the folders and directories there.
From the Python documentation about os.walk:
https://docs.python.org/2/library/os.html
dirpath is a string, the path to the directory. dirnames is a list of
the names of the subdirectories in dirpath (excluding '.' and '..').
filenames is a list of the names of the non-directory files in
dirpath.
With os.path.isfile(dirpath) you are checking whether dirpath is a file, which is never the case. Try changing the code to:
full_filename = os.path.join(dirpath, filename)
if os.path.isfile(full_filename):
print(full_filename, hashlib.md5(open(full_filename, 'rb').read()).digest())
I have a folder (with other subfolders) from which i would like to copy only the .js files to another existing folder (this also has subfolders with the same folder structure as the first one, except this one has only the folders, so no file)
How can i do that with python? I tried shutil.copytree but it fails because some folders already exists.
use os.path.splitext or glob.iglob
glob.iglob(pathname)
Return an iterator which yields the same values as glob() without
actually storing them all simultaneously.
I propose a solution with os.path.splitext, walking with os.walk. I make use of os.path.relpath to find relative path in the duplicate tree.
source_dir is your source uppermost source folder, dest_dir your uppermost destination folder.
import os, shutil, glob
source_dir = "F:\CS\PyA"
dest_dir = "F:\CS\PyB"
for root, dirnames, filenames in os.walk(source_dir):
for file in filenames:
(shortname, extension) = os.path.splitext(file)
if extension == ".txt" :
shutil.copy2(os.path.join(root,file), os.path.join(dest_dir,
os.path.relpath(os.path.join(root,file),source_dir)))
from glob import glob
from shutil import copy
import os
def copyJS(src, dst):
listing = glob(src + '/*')
for f in listing:
if os.path.isdir(f):
lastToken = f.split('/')[-1]
copyJS(src+'/' + lastToken, dst+ '/' + lastToken)
elif f[-3:] == '.js':
copy(f, dst)
I'd like to copy the files that have a specific file extension to a new folder. I have an idea how to use os.walk but specifically how would I go about using that? I'm searching for the files with a specific file extension in only one folder (this folder has 2 subdirectories but the files I'm looking for will never be found in these 2 subdirectories so I don't need to search in these subdirectories). Thanks in advance.
import glob, os, shutil
files = glob.iglob(os.path.join(source_dir, "*.ext"))
for file in files:
if os.path.isfile(file):
shutil.copy2(file, dest_dir)
Read the documentation of the shutil module to choose the function that fits your needs (shutil.copy(), shutil.copy2() or shutil.copyfile()).
If you're not recursing, you don't need walk().
Federico's answer with glob is fine, assuming you aren't going to have any directories called ‘something.ext’. Otherwise try:
import os, shutil
for basename in os.listdir(srcdir):
if basename.endswith('.ext'):
pathname = os.path.join(srcdir, basename)
if os.path.isfile(pathname):
shutil.copy2(pathname, dstdir)
Here is a non-recursive version with os.walk:
import fnmatch, os, shutil
def copyfiles(srcdir, dstdir, filepattern):
def failed(exc):
raise exc
for dirpath, dirs, files in os.walk(srcdir, topdown=True, onerror=failed):
for file in fnmatch.filter(files, filepattern):
shutil.copy2(os.path.join(dirpath, file), dstdir)
break # no recursion
Example:
copyfiles(".", "test", "*.ext")
This will walk a tree with sub-directories. You can do an os.path.isfile check to make it a little safer.
for root, dirs, files in os.walk(srcDir):
for file in files:
if file[-4:].lower() == '.jpg':
shutil.copy(os.path.join(root, file), os.path.join(dest, file))
Copy files with extension "extension" from srcDir to dstDir...
import os, shutil, sys
srcDir = sys.argv[1]
dstDir = sys.argv[2]
extension = sys.argv[3]
print "Source Dir: ", srcDir, "\n", "Destination Dir: ",dstDir, "\n", "Extension: ", extension
for root, dirs, files in os.walk(srcDir):
for file_ in files:
if file_.endswith(extension):
shutil.copy(os.path.join(root, file_), os.path.join(dstDir, file_))