Python - filename.replace does not change the filename - python

I Have a directory with a series of txt files and I want to replace a part of the filenames. Here is an example of the filenames in the directory;
2017 Q2 txt WdCt.txt
2017 Q3 txt WdCt.txt
I want to replace txt WdCt with WdFreq in each file name. Here is the code I wrote to do this:
import os.path
sourcedir = 'C:/Users/Public/EnvDef/Proj/1ErnCls/IOUErnCls/Wd Ct by Qrtr/All Word Count'
os.chdir(sourcedir)
cwd = os.getcwd()
print(' 2 Working Directory is %s' % cwd)
print(' ')
for dirPath, subdirNames, fileList in os.walk(cwd):
for filename in fileList:
print("Old File Name")
print(filename)
filename=filename.replace('txt WdCT','WdFreq')
print ("New File Name")
print(filename)
And the following is an example of the output. It appears that the script does walk through the directory and the output shows the files to be renamed as desired. However, the file names in the directory are NOT changed. I have searched online and found many examples that are like what I am trying to do but I cannot determine why my code does not make a change in the name of the files. Any help and or suggestions will be appreciated.
Working Directory: C:\Users\Public\EnvDef\Proj\1ErnCls\IOUErnCls\Wd Ct by Qrtr\All Word Count
Old File Name:
2017 Q2 txt WdCt.txt
New File Name:
2017 Q2 WdFreq.txt

The problem is that filename=filename.replace('txt WdCT','WdFreq') only changes the string representing the file name. You then need to rename the file using os.rename or shutil.move
import os
sourcedir = 'C:/Users/Public/EnvDef/Proj/1ErnCls/IOUErnCls/Wd Ct by Qrtr/All Word Count'
os.chdir(sourcedir)
cwd = os.getcwd()
print(' 2 Working Directory is %s' % cwd)
print(' ')
for dirPath, subdirNames, fileList in os.walk(cwd):
for filename in fileList:
os.rename(os.path.join(dirPath, filename), os.path.join(dirPath, filename.replace('txt WdCT','WdFreq')))

I second #mechanical_meat's suggestion, you would have to use the method os.rename(source file, destination file). Also, if you are interested on filenames from only a specific directory, I would suggest to take a look at this method os.listdir(directory path) since os.walk() iterates through all files and sub-directories under the specified directory.
A modified version of your code using os.listdir() -
import os
sourcedir = '<your directory path>'
os.chdir(sourcedir)
path = os.getcwd()
filenames = os.listdir(path)
for filename in filenames:
os.rename(filename, filename.replace("txt WdCt.txt", "WdFreq.txt"))

List of changes:
Replaced the use of % string formatting, as was done in Python 2.6.
Replaced os.path with the great pathlib.
Changed variable names to follow proper style conventions.
Removed the superfluous (at best) changing of the working directory.
Code:
import pathlib
source_dir = pathlib.Path("/Users/alexandercecile/Documents/Projects/AdHoc/resources/temp")
for curr_path in source_dir.iterdir():
print(f"{curr_path=}")
new_path = curr_path.rename(source_dir.joinpath(curr_path.name.replace("txt WdCt", "WdFreq")))
print(f"{new_path=}\n")
Output:
curr_path=PosixPath('/Users/alexandercecile/Documents/Projects/AdHoc/resources/temp/2017 Q2 txt WdCt.txt')
new_path=PosixPath('/Users/alexandercecile/Documents/Projects/AdHoc/resources/temp/2017 Q2 WdFreq.txt')
curr_path=PosixPath('/Users/alexandercecile/Documents/Projects/AdHoc/resources/temp/2017 Q3 txt WdCt.txt')
new_path=PosixPath('/Users/alexandercecile/Documents/Projects/AdHoc/resources/temp/2017 Q3 WdFreq.txt')

Related

Filtering files using os.walk()

I'm looking to modify the program to print the contents of any file called log.txt in a given year's subdirectory, ignoring any other file.
import os
year = input('Enter year: ')
path = os.path.join('logs', year)
print()
for dirname, subdirs, files in os.walk(path):
print(dirname, 'contains subdirectories:', subdirs, end=' ')
print('and the files:', files)
Here's what you need to do. I won't provide the complete code:
Iterate over files and check for 'log.txt'.
Get the path to the file. Hint: os.path.join.
open the file and read it.
print out the content

LFW nested folder iteration [duplicate]

I'd like to browse through the current folder and all its subfolders and get all the files with .htm|.html extensions. I have found out that it is possible to find out whether an object is a dir or file like this:
import os
dirList = os.listdir("./") # current directory
for dir in dirList:
if os.path.isdir(dir) == True:
# I don't know how to get into this dir and do the same thing here
else:
# I got file and i can regexp if it is .htm|html
and in the end, I would like to have all the files and their paths in an array. Is something like that possible?
You can use os.walk() to recursively iterate through a directory and all its subdirectories:
for root, dirs, files in os.walk(path):
for name in files:
if name.endswith((".html", ".htm")):
# whatever
To build a list of these names, you can use a list comprehension:
htmlfiles = [os.path.join(root, name)
for root, dirs, files in os.walk(path)
for name in files
if name.endswith((".html", ".htm"))]
I had a similar thing to work on, and this is how I did it.
import os
rootdir = os.getcwd()
for subdir, dirs, files in os.walk(rootdir):
for file in files:
#print os.path.join(subdir, file)
filepath = subdir + os.sep + file
if filepath.endswith(".html"):
print (filepath)
Hope this helps.
In python 3 you can use os.scandir():
def dir_scan(path):
for i in os.scandir(path):
if i.is_file():
print('File: ' + i.path)
elif i.is_dir():
print('Folder: ' + i.path)
dir_scan(i.path)
Use newDirName = os.path.abspath(dir) to create a full directory path name for the subdirectory and then list its contents as you have done with the parent (i.e. newDirList = os.listDir(newDirName))
You can create a separate method of your code snippet and call it recursively through the subdirectory structure. The first parameter is the directory pathname. This will change for each subdirectory.
This answer is based on the 3.1.1 version documentation of the Python Library. There is a good model example of this in action on page 228 of the Python 3.1.1 Library Reference (Chapter 10 - File and Directory Access).
Good Luck!
Slightly altered version of Sven Marnach's solution..
import os
folder_location = 'C:\SomeFolderName'
file_list = create_file_list(folder_location)
def create_file_list(path):
return_list = []
for filenames in os.walk(path):
for file_list in filenames:
for file_name in file_list:
if file_name.endswith((".txt")):
return_list.append(file_name)
return return_list
There are two ways works for me.
1. Work with the `os` package and use `'__file__'` to replace the main
directory when the project locates
import os
script_dir = os.path.dirname(__file__)
path = 'subdirectory/test.txt'
file = os.path.join(script_dir, path)
fileread = open(file,'r')
2. By using '\\' to read or write the file in subfolder
fileread = open('subdirectory\\test.txt','r')
from tkinter import *
import os
root = Tk()
file = filedialog.askdirectory()
changed_dir = os.listdir(file)
print(changed_dir)
root.mainloop()

Keeping renamed text files in original folder

This is my current (from a Jupyter notebook) code for renaming some text files.
The issue is when I run the code, the renamed files are placed in my current working Jupyter folder. I would like the files to stay in the original folder
import glob
import os
path = 'C:\data_research\text_test\*.txt'
files = glob.glob(r'C:\data_research\text_test\*.txt')
for file in files:
os.rename(file, file[-27:])
You should only change the name and keep the path the same. Your filename will not always be longer than 27 so putting this into you code is not ideal. What you want is something that just separates the name from the path, no matter the name, no matter the path. Something like:
import os
import glob
path = 'C:\data_research\text_test\*.txt'
files = glob.glob(r'C:\data_research\text_test\*.txt')
for file in files:
old_name = os.path.basename(file) # now this is just the name of your file
# now you can do something with the name... here i'll just add new_ to it.
new_name = 'new_' + old_name # or do something else with it
new_file = os.path.join(os.path.dirname(file), new_name) # now we put the path and the name together again
os.rename(file, new_file) # and now we rename.
If you are using windows you might want to use the ntpath package instead.
file[-27:] takes the last 27 characters of the filename so unless all of your filenames are 27 characters long, it will fail. If it does succeed, you've stripped off the target directory name so the file is moved to your current directory. os.path has utilities to manage file names and you should use them:
import glob
import os
path = 'C:\data_research\text_test*.txt'
files = glob.glob(r'C:\data_research\text_test*.txt')
for file in files:
dirname, basename = os.path.split(file)
# I don't know how you want to rename so I made something up
newname = basename + '.bak'
os.rename(file, os.path.join(dirname, newname))

renaming files in a directory + subdirectories in python

I have some files that I'm working with in a python script. The latest requirement is that I go into a directory that the files will be placed in and rename all files by adding a datestamp and project name to the beginning of the filename while keeping the original name.
i.e. foo.txt becomes 2011-12-28_projectname_foo.txt
Building the new tag was easy enough, it's just the renaming process that's tripping me up.
Can you post what you have tried?
I think you should just need to use os.walk with os.rename.
Something like this:
import os
from os.path import join
for root, dirs, files in os.walk('path/to/dir'):
for name in files:
newname = foo + name
os.rename(join(root,name),join(root,newname))
I know this is an older post of mine, but seeing as how it's been viewed quite a few times I figure I'll post what I did to resolve this.
import os
sv_name="(whatever it's named)"
today=datetime.date.today()
survey=sv_name.replace(" ","_")
date=str(today).replace(" ","_")
namedate=survey+str(date)
[os.rename(f,str(namedate+"_"+f)) for f in os.listdir('.') if not f.startswith('.')]
import os
dir_name = os.path.realpath('ur directory')
cnt=0 for root, dirs, files in os.walk(dir_name, topdown=False):
for file in files:
cnt=cnt+1
file_name = os.path.splitext(file)[0]#file name no ext
extension = os.path.splitext(file)[1]
dir_name = os.path.basename(root)
try:
os.rename(root+"/"+file,root+"/"+dir_name+extension)
except FileExistsError:
os.rename(root+"/"+file,root+""+dir_name+str(cnt)+extension)
to care if more files are there in single folder and if we need to give incremental value for the files

Browse files and subfolders in Python

I'd like to browse through the current folder and all its subfolders and get all the files with .htm|.html extensions. I have found out that it is possible to find out whether an object is a dir or file like this:
import os
dirList = os.listdir("./") # current directory
for dir in dirList:
if os.path.isdir(dir) == True:
# I don't know how to get into this dir and do the same thing here
else:
# I got file and i can regexp if it is .htm|html
and in the end, I would like to have all the files and their paths in an array. Is something like that possible?
You can use os.walk() to recursively iterate through a directory and all its subdirectories:
for root, dirs, files in os.walk(path):
for name in files:
if name.endswith((".html", ".htm")):
# whatever
To build a list of these names, you can use a list comprehension:
htmlfiles = [os.path.join(root, name)
for root, dirs, files in os.walk(path)
for name in files
if name.endswith((".html", ".htm"))]
I had a similar thing to work on, and this is how I did it.
import os
rootdir = os.getcwd()
for subdir, dirs, files in os.walk(rootdir):
for file in files:
#print os.path.join(subdir, file)
filepath = subdir + os.sep + file
if filepath.endswith(".html"):
print (filepath)
Hope this helps.
In python 3 you can use os.scandir():
def dir_scan(path):
for i in os.scandir(path):
if i.is_file():
print('File: ' + i.path)
elif i.is_dir():
print('Folder: ' + i.path)
dir_scan(i.path)
Use newDirName = os.path.abspath(dir) to create a full directory path name for the subdirectory and then list its contents as you have done with the parent (i.e. newDirList = os.listDir(newDirName))
You can create a separate method of your code snippet and call it recursively through the subdirectory structure. The first parameter is the directory pathname. This will change for each subdirectory.
This answer is based on the 3.1.1 version documentation of the Python Library. There is a good model example of this in action on page 228 of the Python 3.1.1 Library Reference (Chapter 10 - File and Directory Access).
Good Luck!
Slightly altered version of Sven Marnach's solution..
import os
folder_location = 'C:\SomeFolderName'
file_list = create_file_list(folder_location)
def create_file_list(path):
return_list = []
for filenames in os.walk(path):
for file_list in filenames:
for file_name in file_list:
if file_name.endswith((".txt")):
return_list.append(file_name)
return return_list
There are two ways works for me.
1. Work with the `os` package and use `'__file__'` to replace the main
directory when the project locates
import os
script_dir = os.path.dirname(__file__)
path = 'subdirectory/test.txt'
file = os.path.join(script_dir, path)
fileread = open(file,'r')
2. By using '\\' to read or write the file in subfolder
fileread = open('subdirectory\\test.txt','r')
from tkinter import *
import os
root = Tk()
file = filedialog.askdirectory()
changed_dir = os.listdir(file)
print(changed_dir)
root.mainloop()

Categories

Resources