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)
Related
I'm trying to write a python script to move all music files from my whole pc to one spcific folder.
They are scattered everywhere and I want to get them all in one place, so I don't want to copy but completely move them.
I was already able to make a list of all the files with this script:
import os
targetfiles = []
extensions = (".mp3", ".wav", ".flac")
for root, dirs, files in os.walk('/'):
for file in files:
if file.endswith(extensions):
targetfiles.append(os.path.join(root, file))
print(targetfiles)
This prints out a nice list of all the files but I'm stuck to now move them.
I did many diffent tries with different code and this was one of them:
import os
import shutil
targetfiles = []
extensions = (".mp3", ".wav", ".flac")
for root, dirs, files in os.walk('/'):
for file in files:
if file.endswith(extensions):
targetfiles.append(os.path.join(root, file))
new_path = 'C:/Users/Nicolaas/Music/All' + file
shutil.move(targetfiles, new_path)
But everything I try gives me an error:
TypeError: rename: src should be string, bytes or os.PathLike, not list
I think I've met my limit gathering this all as I'm only starting at Python but I would be very grateful if anyone could point me in the right direction!
You are trying to move a list of files to a new location, but the shutil.move function expects a single file as the first argument. To move all the files in the targetfiles list to the new location, you have to use a loop to move each file individually.
for file in targetfiles:
shutil.move(file, new_path)
Also if needed add a trailing slash to the new path 'C:/Users/Nicolaas/Music/All/'
On a sidenote are you sure that moving all files with those extentions is a good idea? I would suggest copying them or having a backup.
Edit:
You can use an if statement to exclude certain folders from being searched.
for root, dirs, files in os.walk('/'):
if any(folder in root for folder in excluded_folders):
continue
for file in files:
if file.endswith(extensions):
targetfiles.append(os.path.join(root, file))
Where excluded_folder is a list of the unwanted folders like: excluded_folders = ['Program Files', 'Windows']
I would suggest using glob for matching:
import glob
def match(extension, root_dir):
return glob.glob(f'**\\*.{extension}', root_dir=root_dir, recursive=True)
root_dirs = ['C:\\Path\\to\\Albums', 'C:\\Path\\to\\dir\\with\\music\\files']
excluded_folders = ['Bieber', 'Eminem']
extensions = ("mp3", "wav", "flac")
targetfiles = [f'{root_dir}\\{file_name}' for root_dir in root_dirs for extension in extensions for file_name in match(extension, root_dir) if not any(excluded_folder in file_name for excluded_folder in excluded_folders)]
Then you can move these files to new_path
So, I created a Python script to batch convert PDF files using Ghostscript. Ideally it should work, but I am not sure why it isn't working. For now, it is going through the input PDF files twice and when it runs the second time, it overwrites the output files.
Here's the script.
from __future__ import print_function
import os
import subprocess
try:
os.mkdir('compressed')
except FileExistsError:
pass
for root, dirs, files in os.walk("."):
for file in files:
if file.endswith(".pdf"):
filename = os.path.join(root, file)
arg1= '-sOutputFile=' + './compressed/' + file
print ("compressing:", file )
p = subprocess.Popen(['gs', '-sDEVICE=pdfwrite', '-dCompatibilityLevel=1.4', '-dPDFSETTINGS=/screen', '-dNOPAUSE', '-dBATCH', '-dQUIET', str(arg1), filename], stdout=subprocess.PIPE).wait()
Here's the ouput.
I am missing what did I do wrong.
file is just the name of the file. You have several files called the same in different directories. Don't forget that os.walk recurses in subdirectories by default.
So you have to save the converted files in a directory or name which depends on root.
and put the output directory outside the current directory as os.walk will scan it
For instance, for flat output replace:
arg1= '-sOutputFile=' + './compressed/' + file
by
arg1= '-sOutputFile=' + '/somewhere/else/compressed/' + root.strip(".").replace(os.sep,"_")+"_"+file
The expression
root.strip(".").replace(os.sep,"_")
should create a "flat" version of root tree without current directory (no dot) and path separators converted to underscores, plus one final underscore. That's one option that would work.
An alternate version that won't scan ./compressed or any other subdirectory (maybe more what you're looking for) would be using os.listdir instead (no recursion)
root = "."
for file in os.listdir(root):
if file.endswith(".pdf"):
filename = os.path.join(root, file)
arg1= '-sOutputFile=' + './compressed/' + file
print ("compressing:", file )
Or os.scandir
root = "."
for entry in os.scandir(root):
file = entry.name
if file.endswith(".pdf"):
filename = os.path.join(root, file)
arg1= '-sOutputFile=' + './compressed/' + file
print ("compressing:", file )
Your problem is that os.walk will also retrieve that contents in "compressed" directory. This is because the files will be compressed and created before os.walk list files in that directory. If you add print(os.path.join(root, file)) to your for-loop you will notice that.
Bellow is a snippet that works since the files retrieved are only the ones in the current directory.
import os
os.makedirs("compressed", exist_ok=True)
for file in os.listdir("."):
if not os.path.isfile(file):
continue
if not file.endswith(".pdf"):
continue
print(file)
os.walk will by definition enter into subdirectories, so you are compressing the files in the compressed subdirectory a second time.
Probably you simply want
for file in os.scandir("."):
...
As an aside, you almost certainly want to avoid Popen in favor of subprocess.run() or one of its legacy variations.
On the first iteration of
for root, dirs, files in os.walk(".")
you find the files in the current directory, then you compress them into the
./compressed/*.pdf path.
After that the second iteration of the outer loop will find the already compressed files in the subdirectory.
Easiest fix is to move the output directory outside of the input directory (or create an input directory next to the compressed dir, and read the files from there instead of .)
I am trying to write a program in python that loops through data from various csv files within a folder. Right now I just want to see that the program can identify the files in a folder but I am unable to have my code print the file names in my folder. This is what I have so far, and I'm not sure what my problem is. Could it be the periods in the folder names in the file path?
import glob
path = "Users/Sarah/Documents/College/Lab/SEM EDS/1.28.20 CZTS hexane/*.csv"
for fname in glob.glob(path):
print fname
No error messages are popping up but nothing will print. Does anyone know what I'm doing wrong?
Are you on a Linux-base system ? If you're not, switch the / for \\.
Is the directory you're giving the full path, from the root folder ? You might need to
specify a FULL path (drive included).
If that still fails, silly but check there actually are files in there, as your code otherwise seems fine.
This code below worked for me, and listed csv files appropriately (see the C:\\ part, could be what you're missing).
import glob
path = "C:\\Users\\xhattam\\Downloads\\TEST_FOLDER\\*.csv"
for fname in glob.glob(path):
print(fname)
The following code gets a list of files in a folder and if they have csv in them it will print the file name.
import os
path = r"C:\temp"
filesfolders = os.listdir(path)
for file in filesfolders:
if ".csv" in file:
print (file)
Note the indentation in my code. You need to be careful not to mix tabs and spaces as theses are not the same to python.
Alternatively you could use os
import os
files_list = os.listdir(path)
out_list = []
for item in files_list:
if item[-4:] == ".csv":
out_list.append(item)
print(out_list)
Are you sure you are using the correct path?
Try moving the python script in the folder when the CSV files are, and then change it to this:
import glob
path = "./*.csv"
for fname in glob.glob(path):
print fname
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)
I'm trying to delete the last several characters of multiple files in a specific directory using the rename function. The code I have written using suggestions on this site looks like it should work, but it returns the error message:
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'test1.txt' -> 'test'
And here is my code:
import os
list = os.listdir("C:\\Users\\Jonathan\\Desktop")
for file in list:
if file.startswith("test"):
os.rename(file, file[0:4])
My code shows that for all files beginning with the word "test", delete all characters after it. As I said, to me it looks like it should work, but I am new at Python, and I don't even understand what the error message means.
Are you actually in the folder where you're renaming? If not, the problem is likely that you're looking in the local folder (where you launched the program). Prepend that path to each file name:
import os
cwd = "C:\\Users\\Jonathan\\Desktop"
list = os.listdir(cwd)
for file in list:
if file.startswith("test"):
os.rename(cwd+file, cwd+"test")
As you didn't specify the complete path to your file, it is likely that your program was saving the in your root directory. Also, you should not use list or file as variable names since they shadow two of Python's types.
import os
files_path = "C:\\Users\\Jonathan\\Desktop\\"
lst = os.listdir(files_path)
for file_name in lst:
if file_name.startswith("test"):
os.rename(files_path + file_name, files_path + file_name[:-4])
Try this:
import os
list = os.listdir("C:\\Users\\Jonathan\\Desktop\\")
for file in list:
if file[:4] == "test":
os.renames(list+file, list+file[:4])
And by the way, if you need find the files and rename them recursively(That means will find all directories in that directory). You can use os.walk() like this:
for root, dirs, files in os.walk("C:\\Users\\Jonathan\\Desktop\\"):
for name in files:
if name[:4] == "test":
os.renames(os.path.join(root, name), os.path.join(root, name)[:4])
you need to use os.rename() with existing paths. if your working directory is not the directory containing the file your script will fail. this should work independently of your working directory:
files_path = "C:\\Users\\Jonathan\\Desktop\\"
lst = os.listdir(files_path)
for fle in lst:
if fle.startswith("test"):
os.rename(os.path.join(files_path, fle),
os.path.join(files_path, fle[:4]) )
and avoid using list as a varaible name.