counting files that DO NOT have a file extension - python

I currently have this;
names = [os.path.basename(x) for x in glob.glob(UserInput[0]+'/*.txt')]
for i in names:
print("file found - "+i)
Works perfectly for counting filenames ending with .txt and obtaining the basename.
However, I have a folder with a done of filetype file. I'd like to find all of the files that do not have an extension associated with them ... I'm pretty stumped how I'd change the /*.txt part to accommodate this. Any suggestions?

pathlib is king.
* is a pattern for all files, 1 level deep.
**/* is a pattern for all files in all subfolders.
import pathlib
for file_ in pathlib.Path(<your path here>).glob("**/*"): # or glob("*")
if not file_.suffix:
print(file_)

Just loop over all the files, and discard the ones which have an extension.
import os
for x in os.scandir(UserInput[0]):
if '.' in x:
continue
print("file found -", x)

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)

Trying to print name of all csv files within a given folder

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

Renaming files in the order they are titled python

I'm using a python script that other guys have helped me with to rename all .jpg or .png files in a directory to whatever I want in order.
So if I have 20 .png files in a directory, I want to rename them in order from 1-20.
The script I have DOES this and I'm happy with it. However, it was just pointed out that the files I have been renaming with this script have been out of order.
As an example, when I rename 1.png to testImage1.png, I'm really renaming testImage10.png as testImage1.png. I tested this with my script by creating 5 text files with the same content, but text files 1-3 I put in different content to keep track of what is what after I'm done renaming. Sure enough, everything is mixed up.
import os
import sys
source = sys.argv[1]
files = os.listdir(source)
name = sys.argv[2]
def rename():
i = 1
for file in files:
os.rename(os.path.join(source, file), os.path.join(source, name+str(i)+'.png'))
i += 1
rename()
I took the time to try and use my (limited) python knowledge to create a series of if/elif statements to sift through and rename the files with the correct name in order.
def roundTwo():
print('Beginning of the end')
i = 1
for root, dirs, files in os.walk(source):
for file in files:
print('Test')
if source == 'newFile0.txt' or 'newFile0.png':
os.rename(os.path.join(source, file), os.path.join(source, name+str(i)+'.txt'))
print('Test1')
i += 1
elif source == 'newFile1.txt' or 'newFile1.png':
os.rename(os.path.join(source, file), os.path.join(source, name+str(i)+'.txt'))
print('Test2')
i += 1
roundTwo()
I did a fair amount of searching to include using Re or fnmatch but nothing comes exactly close to what I'm looking to do. Perhaps I'm using the wrong terms to search? Any insight helps!
If your problem is with 1 and 10, then you can use natural sorting. Sort your variable files as follows:
from natsort import natsorted, ns
natsorted(files, alg=ns.IGNORECASE)
Example:
>>> x = ['a/b/c21.txt', 'a/b/c1.txt', 'a/b/c10.txt', 'a/b/c11.txt', 'a/b/c2.txt']
>>> sorted(x)
['a/b/c1.txt', 'a/b/c10.txt', 'a/b/c11.txt', 'a/b/c2.txt', 'a/b/c21.txt']
>>> natsorted(x, alg=ns.IGNORECASE)
['a/b/c1.txt', 'a/b/c2.txt', 'a/b/c10.txt', 'a/b/c11.txt', 'a/b/c21.txt']
If all the files have some sort of basename you can modify your first function to extract the number assigned to the image
baseName='testImage'
def rename():
for file in files:
number=file[len(baseName):file.find('.png')]
os.rename(os.path.join(source, file), os.path.join(source, name+number+'.png'))
Hope it helps

Python: Removing Leading Zeros in the Filename of Every File in a Folder and Subfolders

I would think that this is a basic task but most of my searches refer to adding zeros. I just want to strip the leading zeros from every file. I have files like "01.jpg, 02.jpg... 09.jpg".
Chapter 9 of Automate the Boring Stuff talks specifically about using python for this task but does not go over any examples of this.
import os, sys
for filename in os.listdir(os.path.dirname(os.path.abspath(__file__))):
Well that is the start of what I have so far.
import os, sys
for filename in os.listdir(file folder):
os.rename(filename, filename[1:])
It removes the first char from all file names (in your case, the '0' that you want to get rid of). I recommend using it with caution because it's irreversible.
Use this to get all files under your root folder:
files = []
for root, directories, file_names in os.walk(unicode(path)):
for filename in file_names:
files.append((filename, root))
return files
then simply iterate over the files and rename:
for f, p in files:
if f.startswith('0'):
os.rename(os.path.join(p, f), os.path.join(p, f[1:])

I am trying to write a Python Script to Print a list of Files In Directory

as the title would imply I am looking to create a script that will allow me to print a list of file names in a directory to a CSV file.
I have a folder on my desktop that contains approx 150 pdf's. I'd like to be able to have the file names printed to a csv.
I am brand new to Python and may be jumping out of the frying pan and into the fire with this project.
Can anyone offer some insight to get me started?
First off you will want to start by grabbing all of the files in the directory, then simply by writing them to a file.
from os import listdir
from os.path import isfile, join
import csv
onlyfiles = [f for f in listdir("./") if isfile(join("./", f))]
with open('file_name.csv', 'w') as print_to:
writer = csv.writer(print_to)
writer.writerow(onlyfiles)
Please Note
"./" on line 5 is the directory you want to grab the files from.
Please replace 'file_name.csv' with the name of the file you want to right too.
The following will create a csv file with all *.pdf files:
from glob import glob
with open('/tmp/filelist.csv', 'w') as fout:
# write the csv header -- optional
fout.write("filename\n")
# write each filename with a newline characer
fout.writelines(['%s\n' % fn for fn in glob('/path/to/*.pdf')])
glob() is a nice shortcut to using listdir because it supports wildcards.
import os
csvpath = "csvfile.csv"
dirpath = "."
f = open("csvpath, "wb")
f.write(",".join(os.listdir(dirpath)))
f.close()
This may be improved to present filenames in way that you need, like for getting them back, or something. For instance, this most probably won't include unicode filenames in UTF-8 form but make some mess out of the encoding, but it is easy to fix all that.
If you have very big dir, with many files, you may have to wait some time for os.listdir() to get them all. This also can be fixed by using some other methods instead of os.listdir().
To differentiate between files and subdirectories see Michael's answer.
Also, using os.path.isfile() or os.path.isdir() you can recursively get all subdirectories if you wish.
Like this:
def getall (path):
files = []
for x in os.listdir(path):
x = os.path.join(path, x)
if os.path.isdir(x): files += getall(x)
else: files.append(x)
return files

Categories