How to have all possibilities of path with specific beginning? - python

I have to check a variable file at a location :
variable = "40014ee0aee34570"
os.path.realpath(/dev/disk/by-id/wwn-0x{0}'.format(variable))
I need to check if there is also 40014ee0aee34570-part1, 40014ee0aee34570-part2 and etc.
For now I can do it like this
os.path.realpath('/dev/disk/by-id/wwn-0x{0}{1}'.format(variable, '-part1')
But how I can do check for every possibility number after part in this line programatically ?
Thank you

I would suggest using glob module.
import glob
variable = "40014ee0aee34570"
# file wildcard, use * at the end to get all suffixes
file_wildcard = "/dev/disk/by-id/wwn-0x{0}*".format(variable)
possible_file_paths = glob.glob(file_wildcard)
for file_path in possible_file_paths:
os.path.realpath(file_path)

You can simply concatenate srtings with +
Example :
string1 = "I am "
string2 = "foo"
string3 = string1 + string2
print(string3)
OUT[1]:
>> I am foo
Thus, you can use it to generate your path to your file programatically with all the components (root path , variable name, suffixes, numbers ,etc..) :
import os
path = r"/dev/disk/by-id/"
file_prefix = "wwn-0x"
variable = "40014ee0aee34570"
file_suffix = "-part"
for number in range(0,10):
file = os.path.join(path , file_prefix + variable + file_suffix + str(number))
if os.path.exists(file):
print(f"{file} exists")
else :
print(f"no file with that part number {number}")

Related

Python: How to change a filename to lowercase but NOT the extension

I'm trying to change filenames like WINDOW.txt to lowercase but then I also need to change the extension .txt to uppercase. I am thinking I can just change the entire thing to lowercase as the extension is already lowercase and then using something like .endswith() to change the extension to uppercase but I can't seem to figure it out. I know this may seem simple to most so thank you for your patience.
This one handles filenames, paths across different operating systems:
import os.path
def lower_base_upper_ext(path):
"""Filename to lowercase, extension to uppercase."""
path, ext = os.path.splitext(path)
head, tail = os.path.split(path)
return head + tail.lower() + ext.upper()
It leaves possible directory names untouched, just the filename portion is lower-cased and extension upper-cased.
oldname='HeLlO.world.TxT'
if '.' in oldname:
(basename, ext) = oldname.rsplit('.', 1)
newname = basename.lower() + '.' + ext.upper()
else:
newname = oldname.lower()
print(f'{oldname} => {newname}')
...properly emits:
HeLlO.world.TxT => hello.world.TXT
name = "MyFile.txt"
new_name = name.rsplit(sep= ".", maxsplit=1)
print(new_name[0].lower()+"."+new_name[1].upper())
filename = "WINDOW.txt"
filename = filename.split('.')
filename = ".".join(filename[0:-1]).lower() + '.' + filename[-1].upper()
print(filename)
>> window.TXT
filename = "foo.bar.maz.txt"
filename = filename.split('.')
filename = ".".join(filename[0:-1]).lower() + '.' + filename[-1].upper()
print(filename)
>> foo.bar.maz.TXT
If I read the question correctly, it wants the lowercase name and upper case file extension, which is weird, but here is a simple solution.
filename = "WINDOW.txt"
ext_ind = filename.rindex('.')
filename = filename[0:ext_ind].lower() + '.' + filename[ext_ind+1:len(filename)].upper()
print(filename)
>> window.TXT

Name definition error when defining variables in function

I have a bit of code that accepts a .csv with a list of filenames as an input, then breaks the filename down into its component parts and re-orders them along with some additional characters.
Input Example:
3006419_3006420_ENG_FRONT.jpg
Output Example:
;E3006419_3006420_FRONT_Image_Container;
However, I'd like to make the portion of the for loop that splits up the filename into a function that I can call elsewhere, so that I can re-use it in a second for loop that outputs in a different format. When I try to define a function, though, it seems I have a scoping error with my variables and can't use them in my output.write statement.
Working Code
from csv import reader
import sys
if len(sys.argv) != 2:
print('USAGE ERROR:\nRun like "python <script.py> <input file.csv>"') #error message if code is not run with correct number of arguments
exit()
file = open(sys.argv[1]) #open input file
output = open('output.impex','w+') #define output impex file
for line in file:
nameAndExtension = line.split('.') #split file into filename and file extension
name = nameAndExtension[0]
extension = nameAndExtension[1].replace('\n','') #save file extension as variable extension and remove \n
elements = name.split('_') #split filename into constituent elements. Filenames are formatted as PARENTSKU_CHILDSKU_LANG_ANGLE.extension, eg '3006419_3006420_ENG_FRONT.jpg'
parentSKU = elements[0]
childSKU = elements[1]
lang = elements[2]
angle = elements[3]
output.write(";E" + parentSKU + "_" + childSKU + "_" + angle + '_Image_Container;\n')
Non-Working Code:
from csv import reader
import sys
if len(sys.argv) != 2:
print('USAGE ERROR:\nRun like "python <script.py> <input file.csv>"') #error message if code is not run with correct number of arguments
exit()
file = open(sys.argv[1]) #open input file
output = open('output.impex','w+') #define output impex file
def lineSplitting(x):
nameAndExtension = x.split('.') #split file into filename and file extension
name = nameAndExtension[0]
extension = nameAndExtension[1].replace('\n','') #save file extension as variable extension and remove \n
elements = name.split('_') #split filename into constituent elements. Filenames are formatted as PARENTSKU_CHILDSKU_LANG_ANGLE.extension, eg '3006419_3006420_ENG_FRONT.jpg'
parentSKU = elements[0]
childSKU = elements[1]
lang = elements[2]
angle = elements[3]
for line in file:
lineSplitting(line)
output.write(";E" + parentSKU + "_" + childSKU + "_" + angle + '_Image_Container;\n')
I get "NameError: name 'parentSKU' is not defined" I think because the of the variable scope - but I don't know what I need to do to make the variable re-usable in the for-loop. What do I need to do to make all that splitting and variable definition into a function?
you should return your value from the function
def lineSplitting(x):
nameAndExtension = x.split('.') #split file into filename and file extension
name = nameAndExtension[0]
extension = nameAndExtension[1].replace('\n','') #save file extension as variable extension and remove \n
elements = name.split('_') #split filename into constituent elements. Filenames are formatted as PARENTSKU_CHILDSKU_LANG_ANGLE.extension, eg '3006419_3006420_ENG_FRONT.jpg'
parentSKU = elements[0]
childSKU = elements[1]
lang = elements[2]
angle = elements[3]
return parentSKU,childSKU,angle
and the next code will call the function
for line in file:
parentSKU,childSKU,angle =lineSplitting(line)
output.write(";E" + parentSKU + "_" + childSKU + "_" + angle + '_Image_Container;\n')

multy line string concatenation and writing to a text file

I am using the os library of python to help me do the following:
Ask the user for a path.
Print all the directories and files included in it.
Save the information in a text file.
this is my code:
import os
text = 'List:'
def print_tree(dir_path,text1):
for name in os.listdir(dir_path):
full_path = os.path.join(dir_path, name)
x = name.find('.')
if x!= -1:
print name #replace with full path if needed
text1 = text1 + name
else:
print '------------------------------------'
text1 = text1 + '------------------------------------'
print name
text1 = text1 + name
if os.path.isdir(full_path):
os.path.split(name)
print '------------------------------------'
text1 = text1 + '------------------------------------'
print_tree(full_path,text1)
path = raw_input('give me a dir path')
print_tree(path,text)
myfile = open('text.txt','w')
myfile.write(text)
I have two problems. First, although there's no error whatsoever, the only thing that actually exists in the text file after running this is 'List:'. Also i don't know how to use string concatenation in order to put each file name on a different line. What am i missing? How can i accomplish this?
Strings are immutable in Python, and the += operator on them is just an illusion. You can concatenate a string all you want in the function, but unless you return it, the string outside the function will not change: text1 = text1 + 'blah' creates a new string, and assigns its reference to text1. The string outside the function has not changed. The solution is to build up a string and then return it:
import os
text = 'List:' + os.linesep
def print_tree(dir_path,text1):
for name in os.listdir(dir_path):
full_path = os.path.join(dir_path, name)
x = name.find('.')
if x!= -1:
print name #replace with full path if needed
text1 = text1 + name + os.linesep
else:
print '------------------------------------'
text1 = text1 + '------------------------------------' + os.linesep
print name
text1 = text1 + name + os.linesep
if os.path.isdir(full_path):
os.path.split(name)
print '------------------------------------'
text1 = text1 + '------------------------------------' + os.linesep
text1 = print_tree(full_path,text1)
return text1
path = raw_input('give me a dir path')
text = print_tree(path,text)
myfile = open('text.txt','w')
myfile.write(text)
I have also take the liberty of appending os.linesep to your concatenated strings. This is done by default by print, so if you want things to look the same, it is a good idea.

Changing the foldername and file name under directory

I am trying to change the foldername, and the file names. They all have a $, and I want a #. Here is what I got
def cleanFiles(self):
#directory = '/Users/eeamesX/work/data/Sept_1_upload/priority_2/transcriptsAudoSplits/09012015_331_male3_r1_seg1/IT_007/hell$o '
directoryChosen = self.directoryChoice()
print directoryChosen + " you made it to files selected"
self.listWidget.addItem(directoryChosen)
#for file_names in os.listdir(directoryChosen):
#self.listWidget.addItem(file_names)
for n in os.listdir(directoryChosen):
print n + " made it here"
if os.path.isfile(directoryChosen):
print directoryChosen + "almost there"
newname = n.replace('$', '#')
print newname + " this is newname"
if newname != n:
os.rename(n,newname)
print '\n--------------------------------\n'
for n in os.listdir(directoryChosen):
print n
self.lblNamechange.show()
I have pinpointed my problem through the printing. It is in the line
if os.path.isfile(directoryChosen):
It is not reading the files in the directory to change the filenames. Any help? Also, Will this change the foldername?
If what you are passing is in fact a directory, then this:
if os.path.isfile(directoryChosen):
will never be True, because isfile checks whether what you are passing is in fact a file.
Running help(os.path.isfile) in your interpreter will show you:
isfile(path)
Test whether a path is a regular file
What you want to use is actually isdir:
if os.path.isdir(directoryChosen):

In Python how to whitelist certain characters in a filename?

To secure uploaded image names, I'd like to strip out image's filenames from anything but string.ascii_letters , string.digits, dot and (one) whitespace.
So I'm wondering what is the best method to check a text against other characters?
import re
import os
s = 'asodgnasAIDID12313%*(#&(!$ 1231'
result = re.sub('[^a-zA-Z\d\. ]|( ){2,}','',s )
if result =='' or os.path.splitext(result)[0].isspace():
print "not a valid name"
else:
print "valid name"
EDIT:
changed it so it will also whitelist only one whitespace + added import re
Not sure if it's what you need but give it a try:
import sys, os
fileName, fileExtension = os.path.splitext('image 11%%22.jpg')
fileExtension = fileExtension.encode('ascii', 'ignore')
fileName = fileName.encode('ascii', 'ignore')
if fileExtension[1:] in ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'tga']:
fileName = ''.join(e for e in fileName if e.isalnum())
print fileName+fileExtension
#image1122.jpg
else:
print "Extension not supported"
isalnum()
https://docs.python.org/2/library/stdtypes.html#str.isalnum
I wouldn't use regex for this. The only tricky requirement is the single space, but that can be done, too.
import string
whitelist = set(string.ascii_letters + string.digits)
good_filename = "herearesomelettersand123numbers andonespace"
bad_filename = "symbols&#! and more than one space"
def strip_filename(fname, whitelist):
"""Strips a filename
Removes any character from string `fname` and removes all but one
whitespace.
"""
whitelist.add(" ")
stripped = ''.join([ch for ch in fname if ch in whitelist])
split = stripped.split()
result = " ".join([split[0], ''.join(split[1:])])
return result
Then call it with:
good_sanitized = strip_filename(good_filename, whitelist)
bad_sanitized = strip_filename(bad_filename, whitelist)
print(good_sanitized)
# 'herearesomelettersand123numbers andonespace'
print(bad_sanitized)
# 'symbols andmorethanonespace'

Categories

Resources