python os.rename ""cannot create a file when that file already exists - python

K.. I'm just using a simple script I found here:
import os
from os import rename, listdir
print os.listdir(".")
for filename in os.listdir("."):
if filename.startswith("colon-"):
print filename
os.rename(filename, filename[7:])
I need to basically take all files like colon-21.mp3 converted to 21.mp3.
But I get the error CANNOT CREATE A FILE WHEN THAT FILE ALREADY EXISTS.
How does one solve this? I am using Windows 7.

The problem is right here:
os.rename(filename, filename[7:])
Python indices start at 0, and the string "colon-" is only 6 characters long, so colon-21.mp3 will become 1.mp3 using your code. Change that line to use filename[6:] instead and your problem should be gone.
That said, using a hard coded string length like you are doing is not a good idea. It is error prone for exactly the reasons we have discovered here (hard coded numbers like this are often called "magic numbers" because it is difficult to tell why they are set to a given length). A superior alternative would be the following:
os.rename(filename, filename.split('-')[1])

Related

How to correctly decode window path in python

I have a question on correctly decode a window path in python. I tried several method online but didn't find a solution. I assigned the path (folder directory) to a variable and would like to read it as raw. However, there is '\' combined with number and python can't read correctly, any suggestion? Thanks
fld_dic = 'D:TestData\20190917_DT19_HigherFlowRate_StdCooler\DM19_Data'
I would like to have:
r'D:TestData\20190917_DT19_HigherFlowRate_StdCooler\DM19_Data'
And I tried:
fr'{fld_dic}' it gives me answer as: 'D:TestData\x8190917_DT19_HigherFlowRate_StdCooler\\DM19_Data'
which is not what I want. Any idea how to change to raw string from an assigned variable with '\' and number combined?
Thanks
The problem's root caused is string assigning. When you assigning like that path='c:\202\data' python encode this string according to default UNICODE. You need to change your assigning. You have to assige as raw string. Also like this path usage is not best practice. It will occure proble continuesly. It is not meet with PEP8
You should not be used path variable as string. It will destroy python cross platform advantage.
You should use pathlib or os.path. I recommend pathlib. It have pure windows and linux path. Also while getting path use this path. If You get path from and input you can read it as raw text and convert to pathlib instance.
Check this link:
https://docs.python.org/3/library/pathlib.html
It works but not best practice. Just replace path assigning as raw string/
import os
def fcn(path=r'C:\202\data'):
print(path)
os.chdir(path)
fcn()

Using os.system to operate a .py file on many files

I hope that I can ask this in a clear way, im very much a beginner to python and forums in general so I apologise if i've got anything wrong from the start!
My issue is that I am currently trying to use os.system() to enable a program to run on every file within a directory (this is a directory of ASCII tables which I am crossing with a series of other tables to find matches.
import os
for filename in os.listdir('.'):
os.system('stilts tmatch2 ifmt1=ascii ifmt2=ascii in1=intern in2= %s matcher=2d values1='col1 col2' values2='col1 col2' params=5 out= %s-table.fits'%(filename,filename))
So what im hoping this would do is for every 'filename' it would operate this program known as stilts. Im guessing this gets interrupted/doesn't work because of the presence of apostrophes ' in the line of code itself, which must disrupt the syntax? (please correct me if I am wrong)
I then replaced the ' in os.system() with "" instead. This, however, stops me using the %s notation to refer to filenames throughout the code (at least I am pretty sure anyway).
import os
for filename in os.listdir('.'):
os.system("stilts tmatch2 ifmt1=ascii ifmt2=ascii in1=intern in2= %s matcher=2d values1='col1 col2' values2='col1 col2' params=5 out= %s-table.fits"%(filename,filename))
This now runs but obviously doesn't work, as it inteferes with the %s input.
Any ideas how I can go about fixing this? are there any alternative ways to refer to all of the other files given by 'filename' without using %s?
Thanks in advance and again, sorry for my inexperience with both coding and using this forum!
I am not familiar with os.system() but maybe if you try do some changes about the string you are sending to that method before it could behave differently.
You must know that in python you can "sum" strings so you can save your commands in a variable and add the filenames as in:
os.system(commands+filename+othercommands+filename)
other problem that could be working is that when using:
for file in os.listdir()
you may be recievin file types instead of the strings of their names. Try using a method such as filename.name to check if this is a different type of thing.
Sorry I cant test my answers for you but the computer I am using is too slow for me to try downloading python.

Long paths in Python on Windows

I have a problem when programming in Python running under Windows. I need to work with file paths, that are longer than 256 or whatsathelimit characters.
Now, I've read basically about two solutions:
Use GetShortPathName from kernel32.dll and access the file in this way.
That is nice, but I cannot use it, since I need to use the paths in a way
shutil.rmtree(short_path)
where the short_path is a really short path (something like D:\tools\Eclipse) and the long paths appear in the directory itself (damn Eclipse plugins).
Prepend "\\\\?\\" to the path
I haven't managed to make this work in any way. The attempt to do anything this way always result in error WindowsError: [Error 123] The filename, directory name, or volume label syntax is incorrect: <path here>
So my question is: How do I make the 2nd option work? I stress that I need to use it the same way as in the example in option #1.
OR
Is there any other way?
EDIT: I need the solution to work in Python 2.7
EDIT2: The question Python long filename support broken in Windows does give the answer with the 'magic prefix' and I stated that I know it in this question. The thing I do not know is HOW do I use it. I've tried to prepend that to the path but it just failed, as I've written above.
Well it seems that, as always, I've found the answer to what's been bugging me for a week twenty minutes after I seriously ask somebody about it.
So I've found that I need to make sure two things are done correctly:
The path can contain only backslashes, no forward slashes.
If I want to do something like list a directory, I need to end the path with a backslash, otherwise Python will append /*.* to it, which is a forward slash, which is bad.
Hope at least someone will find this useful.
Let me just simplify this for anyone looking for a straight answer:
For python < 3: Path needs to be unicode, prepend string with u like u'C:\\path\\to\\file'
Path needs to start with \\\\?\\ (which is escaped into \\?\) like u'\\\\?\\C:\\path\\to\\file'
No forward slashes only backslashes: / --> \\
It has to be an absolute path; it does not work for relative paths
py 3.8.2
# Fix long path access:
import ntpath
ntpath.realpath = ntpath.abspath
# Fix long path access.
In my case, this solved the problem of running a script from a long path.
(https://developers.google.com/drive/api/v3/quickstart/python)
But this is not a universal fix.
It looks like the ntpath.realpath implementation has problems. This code replaced it with a dummy.
it works for me
import os
str1=r"C:\Users\manual\demodfadsfljdskfjslkdsjfklaj\inner-2djfklsdfjsdklfj\inner3fadsfksdfjdklsfjksdgjl\inner4dfhasdjfhsdjfskfklsjdkjfleioreirueewdsfksdmv\anotherInnerfolder4aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\5qbbbbbbbbbbbccccccccccccccccccccccccsssssssssssssssss\tmp.txt"
print(len(str1)) #346
path = os.path.abspath(str1)
if path.startswith(u"\\\\"):
path=u"\\\\?\\UNC\\"+path[2:]
else:
path=u"\\\\?\\"+path
with open(path,"r+") as f:
print(f.readline())
if you get a long path(more then 258 char) issue in windows then try this .

Python. Error when trying to create a new directory using the filename if it has a special character in it

My script searches the directory that it's in and will create new directories using the file names that it has found and moves them to that directory: John-doe-taxes.hrb -> John-doe/John-does-taxes.hrb. It works fine until it runs into an umlaut character then it will create the directory and return an "Error 2" saying that it cannot find the file. I'm fairly new to programming and the answers i've found have been to add a
coding: utf-8
line to the file which doesn't work I believe because i'm not using umlauts in my code i'm dealing with umlaut files. One thing I was curious about, does this problem just occur with umlauts or other special characters as well? This is the code i'm using, I appreciate any advice provided.
import os
import re
from os.path import dirname, abspath, join
dir = dirname(abspath(__file__))
(root, dirs, files) = os.walk(dir).next()
p = re.compile('(.*)-taxes-')
count = 0
for file in files:
match = p.search(file)
if match:
count = count + 1
print("Files processed: " + str(count))
dir_name = match.group(1)
full_dir = join(dir, dir_name)
if not os.access(full_dir, os.F_OK):
os.mkdir(full_dir)
os.rename(join(dir, file), join(full_dir, file))
raw_input()
I think your problem is passing strs to os.rename that aren't in the system encoding. As long as the filenames only use ascii characters this will work, however outside that range you're likely to run into problems.
The best solution is probably to work in unicode. The filesystem functions should return unicode strings if you give them unicode arguments. open should work fine on windows with unicode filenames.
If you do:
dir = dirname(abspath(unicode(__file__)))
Then you should be working with unicode strings the whole way.
One thing to consider would be to use Python 3. It has native support for unicode as the default. I'm not sure if you would have to do anything to change anything in the above code for it to work, but there is a python script in the examples to transition Python2 code to Python3.
Sorry I can't help you with Python2, I had a similar problem and just transitioned my project to Python3--ended up just being a bit easier for me!

Python os.getcwd paths

I'm using os.listdir() to get all the files from a directory and dump them out to a txt file. I'm going to use the txt file to import into access to generate hyperlinks. The problem I'm having is getting the correct path. So when the script is ran it uses whatever directory you are in. Here is an example. Right now it half works, it create links.txt, but there is nothing in the text file.
myDirectory = os.listdir("links")
f.open("links.txt", "w")
f.writelines([os.getcwd %s % (f) for f in myDirectory])
This line of yours:
f.writelines([os.getcwd %s % (f) for f in myDirectory])
is invalid Python syntax and it's very hard to guess what you had in mind for it -- for example, why would you care about the current directory when myDirectory lists, not files in the current directory, but rather files in subdirectory "links"?
Trying to read your mind is always a difficult and generally unrewarding exercise, but assuming you do mean to use the current directory, you might want
f.writelines(os.path.join(os.getcwd(), f) for f in myDirectory)
You have to call os.getcwd() with the trailing parens.
What you probably actually want here though is os.path.join()
os.getcwd is a function you need to call... also I'm not sure what you're doing with the string escape % - but they only work inside strings... I'm guessing you want something like this:
f.writelines([os.path.join(os.getcwd(),f) for f in myDirectory])
[Edit: os.path.join from Alex Martelli's better answer]

Categories

Resources