open file in python without file's full name? - python

I am trying to execute f = open('filename') in python.
However, I dont know the full name of the file. All I know is that it starts with 's12' and ends with '.ka',I know the folder where it's located, and I know it is the only file in that folder that starts and ends with "s12" and ".ka". Is there a way to do this?

Glob is your friend:
from glob import glob
filename = glob('s12*.ka')[0]
Careful though, glob returns a list of all files matching this pattern so you might want to assert that you get the file you actually want somehow.

Related

Python add prefix to file names inside a directory

I need to add a prefix to file names within a directory. Whenever I try to do it though, it tries to add the prefix to the beginning of the file path. That won't work. I have a few hundred files that I need to change, and I've been stuck on this for a while. Have any ideas? Here's the closest I've come to getting it to work. I found this idea in this thread: How to add prefix to the files while unzipping in Python? If I could make this work inside my for loop to download and extract the files that would be cool, but it's okay if this happens outside of that loop.
import os
import glob
import pathlib
for file in pathlib.Path(r'C:\Users\UserName\Desktop\Wells').glob("*WaterWells.*"):
dst = f"County_{file}"
os.rename(file, os.path.join(file, dst))
That produces this error:
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: 'C:\\Users\\UserName\\Desktop\\Wells\\Alcona_WaterWells.cpg' -> 'C:\\Users\\UserName\\Desktop\\Wells\\Alcona_WaterWells.cpg\\County_C:\\Users\\UserName\\Desktop\\Wells\\Alcona_WaterWells.cpg'
I'd like to add "County_" to each file. The targeted files use this syntax: CountyName_WaterWells.ext
os.path.basename gets the file name, os.path.dirname gets directory names. Note that these may break if your slashes are in a weird direction. Putting them in your code, it would work like this
import os
import glob
import pathlib
for file in pathlib.Path(r'C:\Users\UserName\Desktop\Wells').glob("*WaterWells.*"):
dst = f"County_{os.path.basename(file)}"
os.rename(file, os.path.join(os.path.dirname(file), dst))
The problem is your renaming variable, dst, adds 'County_' before the entire path, which is given by the file variable.
If you take file and break it up with something like file.split("/") (where you should replace the slash with whatever appears between directories when you print file to terminal) then you should be able to get file broken up as a list, where the final element will be the current filename. Modify just this in the loop, put the whole thing pack together using "".join(_path + modified_dst) and then pass this to os.rename.

Python string alphabet removal?

So in my program, I am reading in files and processing them.
My output should say just the file name and then display some data
When I am looping through files and printing output by their name and data,
it displays for example: myfile.txt. I don't want the .txt part. just myfile.
how can I remove the .txt from the end of this string?
The best way to do it is in the example
import os
filename = 'myfile.txt'
print(filename)
print(os.path.splitext(filename))
print(os.path.splitext(filename)[0])
More info about this very useful builtin module
https://docs.python.org/3.8/library/os.path.html
The answers given are totally right, but if you have other possible extensions, or don't want to import anything, try this:
name = file_name.rsplit(".", 1)[0]
You can use pathlib.Path which has a stem attribute that returns the filename without the suffix.
>>> from pathlib import Path
>>> Path('myfile.txt').stem
'myfile'
Well if you only have .txt files you can do this
file_name = "myfile.txt"
file_name.replace('.txt', '')
This uses the built in replace functionality. You can find more info on it here!

Errors with Glob while outputting file names

I am combining two questions here because they are related to each other.
Question 1: I am trying to use glob to open all the files in a folder but it is giving me "Syntax Error". I am using Python 3.xx. Has the syntax changed for Python 3.xx?
Error Message:
File "multiple_files.py", line 29
files = glob.glob(/src/xyz/rte/folder/)
SyntaxError: invalid syntax
Code:
import csv
import os
import glob
from pandas import DataFrame, read_csv
#extracting
files = glob.glob(/src/xyz/rte/folder/)
for fle in files:
with open (fle) as f:
print("output" + fle)
f_read.close()
Question 2: I want to read input files, append "output" to the names and print out the names of the files. How can I do that?
Example: Input file name would be - xyz.csv and the code should print output_xyz.csv .
Your help is appreciated.
Your first problem is that strings, including pathnames, need to be in quotes. This:
files = glob.glob(/src/xyz/rte/folder/)
… is trying to divide a bunch of variables together, but the leftmost and rightmost divisions are missing operands, so you've confused the parser. What you want is this:
files = glob.glob('/src/xyz/rte/folder/')
Your next problem is that this glob pattern doesn't have any globs in it, so the only thing it's going to match is the directory itself.
That's perfectly legal, but kind of useless.
And then you try to open each match as a text file. Which you can't do with a directory, hence the IsADirectoryError.
The answer here is less obvious, because it's not clear what you want.
Maybe you just wanted all of the files in that directory? In that case, you don't want glob.glob, you want listdir (or maybe scandir): os.listdir('/src/xyz/rte/folder/').
Maybe you wanted all of the files in that directory or any of its subdirectories? In that case, you could do it with rglob, but os.walk is probably clearer.
Maybe you did want all the files in that directory that match some pattern, so glob.glob is right—but in that case, you need to specify what that pattern is. For example, if you wanted all .csv files, that would be glob.glob('/src/xyz/rte/folder/*.csv').
Finally, you say "I want to read input files, append "output" to the names and print out the names of the files". Why do you want to read the files if you're not doing anything with the contents? You can do that, of course, but it seems pretty wasteful. If you just want to print out the filenames with output appended, that's easy:
for filename in os.listdir('/src/xyz/rte/folder/'):
print('output'+filename)
This works in http://pyfiddle.io:
Doku: https://docs.python.org/3/library/glob.html
import csv
import os
import glob
# create some files
for n in ["a","b","c","d"]:
with open('{}.txt'.format(n),"w") as f:
f.write(n)
print("\nFiles before")
# get all files
files = glob.glob("./*.*")
for fle in files:
print(fle) # print file
path,fileName = os.path.split(fle) # split name from path
# open file for read and second one for write with modified name
with open (fle) as f,open('{}{}output_{}'.format(path,os.sep, fileName),"w") as w:
content = f.read() # read all
w.write(content.upper()) # write all modified
# check files afterwards
print("\nFiles after")
files = glob.glob("./*.*") # pattern for all files
for fle in files:
print(fle)
Output:
Files before
./d.txt
./main.py
./c.txt
./b.txt
./a.txt
Files after
./d.txt
./output_c.txt
./output_d.txt
./main.py
./output_main.py
./c.txt
./b.txt
./output_b.txt
./a.txt
./output_a.txt
I am on windows and would use os.walk (Doku) instead.
for d,subdirs,files in os.walk("./"): # deconstruct returned aktDir, all subdirs, files
print("AktDir:", d)
print("Subdirs:", subdirs)
print("Files:", files)
Output:
AktDir: ./
Subdirs: []
Files: ['d.txt', 'output_c.txt', 'output_d.txt', 'main.py', 'output_main.py',
'c.txt', 'b.txt', 'output_b.txt', 'a.txt', 'output_a.txt']
It also recurses into subdirs.

Extracting all file names in python

I have a application that converts from one photo format to another by inputting in cmd.exe following: "AppConverter.exe" "file.tiff" "file.jpeg"
But since i don't want to input this every time i want a photo converted, i would like a script that converts all files in the folder. So far i have this:
def start(self):
for root, dirs, files in os.walk("C:\\Users\\x\\Desktop\\converter"):
for file in files:
if file.endswith(".tiff"):
subprocess.run(['AppConverter.exe', '.tiff', '.jpeg'])
So how do i get the names of all the files and put them in subprocess. I am thinking taking basename (no ext.) for every file and pasting it in .tiff and .jpeg, but im at lost on how to do it.
I think the fastest way would be to use the glob module for expressions:
import glob
import subprocess
for file in glob.glob("*.tiff"):
subprocess.run(['AppConverter.exe', file, file[:-5] + '.jpeg'])
# file will be like 'test.tiff'
# file[:-5] will be 'test' (we remove the last 5 characters, so '.tiff'
# we add '.jpeg' to our extension-less string
All those informations are on the post I've linked in the comments o your original question.
You could try looking into os.path.splitext(). That allows you to split the file name into a tuple containing the basename and extension. That might help...
https://docs.python.org/3/library/os.path.html

getting a list of files in a custom directory using glob()

Im trying to write a program that renames files when a use input their own custom file directory.
I'm at a very early part of it. And this is my first time using the OS and glob commands.
My code is below. However when I tried running that, the result was an empty list. I tried typing a file root directory into the glob command directly, it somehow works, but the result isn't what I wanted.
Hope you guys can help me.
Thanks.
import os, glob
def fileDirectory():
#Asks the user for a file root directory
fileroot = raw_input("Please input the file root directory \n\n")
#Returns a list with all the files inside the file root directory
filelist = glob.glob(fileroot)
print filelist
fileDirectory()
Python is white-space sensitive, so you need to make sure that everything you want inside the function is indented.
Stackoverflow has its own indentation requirements for code, which makes it hard to be sure what indentation your code originally had.
import os, glob
def fileDirectory():
#Asks the user for a file root directory
fileroot = raw_input("Please input the file root directory \n\n")
#Returns a list with all the files inside the file root directory
filelist = glob.glob(fileroot)
print filelist
fileDirectory()
The next thing is that glob returns a the results of a glob - it doesn't list a directory, which appears to be what you're trying to do.
Either you want os.listdir, or os.walk or you actually should ask for a glob expression rather than a directory.
Finally raw_input might give you some extra whitespace that you'll have to strip off. Check what fileroot is.
You might want to split up your program, so that you can investigate each function separately.

Categories