Adding extension to multiple files (Python3.5) - python

I have a bunch of files that do not have an extension to them.
file needs to be file.txt
I have tried different methods (didn't try the complicated ones since I am just learning to do a bit of advanced python).
here is one that I tried:
import os
pth = 'B:\\etc'
os.chdir(pth)
for files in os.listdir('.'):
changeName = 'files{ext}'.format(ext='.txt')
I tried the append, replace and rename methods as well and it didn't work for me. or those don't work in the 1st place with what I am trying to do?
What am I missing or doing wrong?.

You need os.rename. But before that,
Check to make sure they aren't folders (thanks, AGN Gazer)
Check to make sure those files don't have extensions already. You can do that with os.path.splitext.
import os
root = os.getcwd()
for file in os.listdir('.'):
if not os.path.isfile(file):
continue
head, tail = os.path.splitext(file)
if not tail:
src = os.path.join(root, file)
dst = os.path.join(root, file + '.txt')
if not os.path.exists(dst): # check if the file doesn't exist
os.rename(src, dst)

Related

Python to rename files in a directory/folder to csv

I have written a small script to hopefully iterate through my directory/folder and replace act with csv. Essentially, I have 11 years worth of files that have a .act extension and I just want to replace it with .csv
import os
files = os.listdir("S:\\folder\\folder1\\folder2\\folder3")
path = "S:\\folder\\folder1\\folder2\\folder3\\"
#print(files)
for x in files:
new_name = x.replace("act","csv")
os.rename(path+x,path+new_name)
print(new_name)
When I execute this, it worked for the first five files and then failed on the sixth with the following error:
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'S:\\folder\\folder1\\folder2\\folder3\\file_2011_06.act' -> 'S:\\folder\\folder1\\folder2\\folder3\\file_2011_06.csv'
When I searched for "S:\folder\folder1\folder2\folder3\file_2011_06.act" in file explorer, the file opens. Are there any tips on what additional steps I can take to debug this issue?
Admittedly, this is my first programming script. I'm trying to do small/minor things to start learning. So, I likely missed something... Thank you!
In your solution, you use string's replace to replace "act" by "csv". This could lead to problems if your path contains "act" somewhere else, e.g., S:\\facts\\file_2011_01.act would become S:\\fcsvs\\file_2011_01.act and rename will throw a FileNotFoundError because rename cannot create folders.
When dealing with file names (e.g., concatenating path fragments, extracting file extensions, ...), I recommend using os.path or pathlib instead of direct string manipulation.
I would like to propose another solution using os.walk. In contrast to os.listdir, it recursively traverses all sub-directories in a single loop.
import os
def act_to_csv(directory):
for root, folders, files in os.walk(directory):
for file in files:
filename, extension = os.path.splitext(file)
if extension == '.act':
original_filepath = os.path.join(root, file)
new_filepath = os.path.join(root, filename + '.csv')
print(f"{original_filepath} --> {new_filepath}")
os.rename(original_filepath, new_filepath)
Also, I'd recommend to first backup your files before manipulating them with scripts. Would be annoying to loose data or see it becoming a mess because of a bug in a script.
import os
folder="S:\\folder\\folder1\\folder2\\folder3\\"
count=1
for file_name in os.listdir(folder):
source = folder + file_name
destination = folder + str(count) + ".csv"
os.rename(source, destination)
count += 1
print('All Files Renamed')
print('New Names are')
res = os.listdir(folder)
print(res)

Renaming files with python to 1.jpg, 2.jpg, etc

First I would like to say I want to do this in python 2.7!
Hi, I have a folder full of images named 1.jpg, 2.jpg, 3.jpg, etc. All the way up to 600.jpg.
I would like to rename them 600 higher, so 601.jpg, 602.jpg, 603.jpg, etc. All the way up to 1200.jpg.
I am honestly not quite sure where to start, so any help would be useful. It doesn't seam like it should be hard but I was not able to name them in ascending order. The best I got was 601.jpg, 601.jpg, and it was the same for every file.
This is what I have currently, it's been altered a few times, and now all I get is an error.
import os
path = '/Users/antse/OneDrive/Documents/Instagram/set_2'
files = os.listdir(path)
i = 601
for file in files:
os.rename(os.path.join(path, file), os.path.join(path, str(i)+'.jpg'))
i = i+1
One of the problems with your approach is that listdir doesn't come back in order from 1.jpg ..., and it includes any other files or subdirectories. But there is no need to list the directory - you already know the pattern of what you want to change and its a hassle to deal with other files that may be there.
import os
path = '/Users/antse/OneDrive/Documents/Instagram/set_2'
for i in range(1, 601):
old_name = os.path.join(path, '{}.jpg'.format(i))
new_name = os.path.join(path, '{}.jpg'.format(i+600))
try:
os.rename(old_name, new_name)
except OSError as e:
print 'could not rename', old_name, e

Copy files from multiple directories into one directory using Python

What is the easiest way to copy files from multiple directories into just one directory using python? To be more clear, I have a tree that looks like this
+Home_Directory
++folder1
-csv1.csv
-csv2.csv
++folder2
-csv3.csv
-csv4.csv
and I want to put csv1,csv2,...etc all into some specified directory without the folder hierarchy.
+some_folder
-csv1.csv
-csv2.csv
-csv3.csv
-csv4.csv
Some solutions I have looked at:
Using shutil.copytree will not work because it will preserve the file structure which is not what I want.
The code I am playing with is very similar to what is posted in this question:
copy multiple files in python
the problem is that I do not know how to do this iteratively. Presumably it would just be another for loop on top of this but I am not familiar enough with the os and shutil libraries to know exactly what I am iterating over. Any help on this?
This is what I thought of. I am assuming you are only pulling csv files from 1 directory.
RootDir1 = r'*your directory*'
TargetFolder = r'*your target folder*'
for root, dirs, files in os.walk((os.path.normpath(RootDir1)), topdown=False):
for name in files:
if name.endswith('.csv'):
print "Found"
SourceFolder = os.path.join(root,name)
shutil.copy2(SourceFolder, TargetFolder) #copies csv to new folder
Edit: missing a ' at the end of RootDir1. You can also use this as a starting guide to make it work as desired.
import glob
import shutil
#import os
dst_dir = "E:/images"
print ('Named explicitly:')
for name in glob.glob('E:/ms/*/*/*'):
if name.endswith(".jpg") or name.endswith(".pdf") :
shutil.copy(name, dst_dir)
print ('\t', name)
You can use it to move all subfolders from the same to a different directory to wherever you want.
import shutil
import os
path=r'* Your Path*'
arr = os.listdir(path)
for i in range(len(arr)):
source_dir=path+'/'+arr[i]
target_dir = r'*Target path*'
file_names = os.listdir(source_dir)
for file_name in file_names:
shutil.move(os.path.join(source_dir, file_name), target_dir)

Create directories based on filenames

I am an absolute beginner to programming so I apologize if this is really basic. I've looked at other questions that appear to be related, but haven't found a solution to this particular problem--at least not that I can understand.
I need to generate a list of files in a directory; create a separate directory for each of those files with the directory name being based on each file's name; and put each file in its corresponding directory.
You should have a look at the glob, os and shutil libraries.
I've written an example for you. This will remove the file extension of each file in a given folder, create a new subdirectory, and move the file into the corresponding folder, i.e.:
C:\Test\
-> test1.txt
-> test2.txt
will become
C:\Test\
-> test1\
-> test1.txt
-> test2\
-> test2.txt
Code:
import glob, os, shutil
folder = 'C:/Test/'
for file_path in glob.glob(os.path.join(folder, '*.*')):
new_dir = file_path.rsplit('.', 1)[0]
os.mkdir(os.path.join(folder, new_dir))
shutil.move(file_path, os.path.join(new_dir, os.path.basename(file_path)))
This will throw an error if the folder already exist. To avoid that, handle the exception:
import glob, os, shutil
folder = 'C:/Test/'
for file_path in glob.glob(os.path.join(folder, '*.*')):
new_dir = file_path.rsplit('.', 1)[0]
try:
os.mkdir(os.path.join(folder, new_dir))
except WindowsError:
# Handle the case where the target dir already exist.
pass
shutil.move(file_path, os.path.join(new_dir, os.path.basename(file_path)))
PS: This will not work for files without extensions. Consider using a more robust code for cases like that.
Here is some advice on listing files using Python.
To create a directory, use os.mkdir (docs). To move a file, use os.rename (docs) or shutil.move (docs).

Open and read sequential XML files with unknown files names in Python

I wish to read incoming XML files that have no specific name (e.g. date/time naming) to extract values and perform particular tasks.
I can step through the files but am having trouble opening them and reading them.
What I have that works is:-
import os
path = 'directory/'
listing = os.listdir(path)
for infile in listing:
print infile
But when I add the following to try and read the files it errors saying No such file or directory.
file = open(infile,'r')
Thank you.
You need to provide the path to file too:
file = open(os.path.join(path,infile),'r')
os.listdir provides the base names, not absolute paths. You'll need to do os.path.join(path, infile) instead of just infile (that may still be a relative path, which should be fine; if you needed an absolute path, you'd feed it through os.path.abspath).
As an alternative to joining the directory path and filename as in the other answers, you can use the glob module. This can also be handy when your directories might contain other (non-XML) files that you don't want to process:
import glob
for infile in glob.glob('directory/*.xml'):
print infile
You have to join the directory path and filename, using
os.path.join(path, infile)
Also use the path without the / :
path = 'directory'
Something like this (Not optimized, just a small change in your code):
import os
path = 'directory'
listing = os.listdir(path)
for infile in listing:
print infile
file_abs = os.path.join(path, infile)
file = open(file_abs,'r')

Categories