I have the following code , but it traverses the 1st directory it finds and stops.
I feel i have the recursive function which should have given the other directories too.
Can anyone please point out what is wrong with this code.
def func(path,no):
no=no+2
for item in os.listdir(path):
if os.path.isfile(path+"\\"+item):
print no * "-" + " " + item
if os.path.isdir(path+"\\"+item):
path=path + "\\" + item
print no * "-" + " " + item
func(path,no)
path="D:\\Hello"
no=0
func(pah,no)
OUTPUT :
-- 1.txt
-- 2.txt
-- 3.txt
-- blue
---- 33.txt
---- 45.txt
---- 56.txt
---- Tere
"blue" & "tere" are the directories. There are more directories int the "HELLO" folder which is not printed.
To walk through directories recursivly, use os.walk
import os
path = r'path\to\root\dir'
for root, dirs, files in os.walk(path):
# Access subdirs and files
On another note:
To join parts of a path together, use os.path.join. So instead of path+"\\"+item you could use os.path.join(path, item). This will work on all platforms, and you don't have to think about escaping slashes etc.
A better way to print values is to use the format method. In your case you could write
print '{} {}'.format(no*'-', item)`
instead of
print no * "-" + " " + item
It's because you change the path value to path + "\\" + item when you first find a directory. Then os.path.isfile(path+"\\"+item) and os.path.isdir(path+"\\"+item) all return False.
It should be like this:
def func(path,no):
no=no+2
for item in os.listdir(path):
if os.path.isfile(path+"\\"+item):
print no * "-" + " " + item
if os.path.isdir(path+"\\"+item):
print no * "-" + " " + item
func(path + "\\" + item,no)
Related
I'm trying to change a lot of file names at once but have run into a problem I can not figure out. I have a list of filenames that all start with "#### - "
i.e. "1942 - testfile001.txt"
all files start with a "yyyy - " a four digit year, a space, a dash, and a space ...
I want to remove all of this "yyyy - " and keep the rest
#!/usr/bin/env python
from os import rename, listdir
badprefix = "1942 - "
fnames = listdir('H:/testing/1928-1949/')
for fname in fnames:
if fname.startswith(badprefix):
rename(fname, fname.replace(badprefix, '', 1))
When I use the specific text above, badprefix = "1942 - ", it works for only files that of course start with 1942
any time I try to throw in a wildcard (#,*,?), badprefix = "19## - " or badprefix = "19?? - " it doesn't work.
My questions are:
In the badprefix variable, what would I use so that any and all files that start with "#### - " are included?
What should I be reading to understand what I am doing wrong?
Would this code solve your problem?
import os, glob
path = "/tmp/test/"
files = "*.txt"
dummy_year = "1234 - "
for oldpath in glob.glob(path + files):
newpath = path + oldpath[len(path)+len(dummy_year):]
print("from: ", oldpath, "to:", newpath)
os.rename(oldpath, newpath)
It renames
1234 - cdef abc sdf.txt
1946 - abcde sdf.txt
to
abcde sdf.txt
cdef abc sdf.txt
I am trying to download a .zip file from ftp site, (works independent of the error), I am creating a folder in a directory with the current date in the name. I want the downloaded zip file to be placed in the newly created folder. my code is below.
import os
import urllib
import datetime
now = datetime.datetime.now()
situs = "ftp://pbcgis:sigcbp#ftp.co.palm-beach.fl.us/CWGIS/SITUS_PUB.zip"
path = os.path.join(r"Y:\JH_Data_Dump\SITUS\PBC_SITUS" + str(now.month) + "_" + str(now.day) + "_" + str(now.year))
path1 = os.path.join(path + "PBC_SITUS" + str(now.month) + "_" + str(now.day) + "_" + str(now.year) +".zip")
print "Creating new directory..."
os.makedirs(path)
print "beginning PBC SITUS Download..."
urllib.urlretrieve(situs, path1)
I get no errors and the file downloads successfully but its not placing the .zip into my newly created folder, its placing it the same directory as the folder but not inside.
You use os.path.join incorrectly. Path segments - directories and filename - are distinct arguments. They are joined using path separator, either \ or /.
path = os.path.join('Y:', "PBC_SITUS123")
path1 = os.path.join(path, "PBC_SITUS123" + ".zip")
will result in Y:\PBC_SITUS123\PBC_SITUS123.zip
I figured out why, I was missing a "\" in the path1 string
it should read:
path1 = os.path.join(path + r"\PBC_SITUS" + str(now.month) + "_" + str(now.day) + "_" + str(now.year) +".zip")
I want to write a file searching code where I don't know if the directory I'm searching in has subdirectories and I want to check that so I don't get an error like this:
[Error 267]The directory name is invalid: 'C:/Path/To/Directory'.
I wrote a code like this where if it finds the file it breaks and stopps the program but if not it goes down a layer and so on.
filename = raw_input('> ')
path = 'C:/Path/Of/Directory/You/Want/To/Search/In'
fldr = os.listdir(path)
for f in fldr:
p = path + '/' + f
sfldr = os.listdir(p)
if os.path.exists(p + '/' + filename):
print 'Found file!!', p + '/' + filename
break
else:
for sf in sfldr:
pp = p + '/' + sf
ssfldr = os.listdir(pp)
if os.path.exists(pp + '/' + filename):
print 'Found file!!', pp + '/' + filename
break
else:
for ssf in ssfldr:
ppp = pp + '/' + ssf
sssfldr = os.listdir(ppp)
if os.path.exists(ppp + '/' + filename):
print 'Found file!!', ppp + '/' + filename
break
The easy to notice error is that when the directory doesn't have 3 layers of subfolders the program just breaks and gives an error message.So if I could check if the folder has subfolders before entering it,that would be neat.
Use os.scandir(). Provides better speed over os.walk()
Link to docs here!
Alternatively use, glob
>>> from glob import glob
>>> paths = glob('*/')
>>> paths
['bin/', 'content/', 'include/', 'lib/', 'output/']
>>>
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):
I have a python tool to 'touch' (utime) a file, then move to another folder. However, if the file already exists in the destination folder, it is silently overwritten. I would like to check for a file of the same name in the destination folder and, if it exists, rename the one I am moving to its name plus '-n' at the end, where n is a number starting at '1' and, if the file with '-1' at the end already exists, '-2' etc.
For example, say in the source folder is a file 'foo.txt', but there is one 'foo.txt' in the destination folder as well. This function should return '(absolute path)/foo-1.txt'.
So, I have made a function to check for these circumstances and return the modified string, so I can use rename later and not overwrite. However, currently, if the file exists, it returns nothing. Following is the function code, assuming these vars:
fileName - input filepath, absolute path. e.g. /Users/foo/sourceFolder/bar.txt
index - iterator variable, set to '1' at the start of each file being opened (externally to function)
def checkExists(fileName):
global index
print "checkExists(" + fileName + ")"
if exists(fileName):
splitPath = split(newFile)
splitName = splitext(splitPath[1])
newSplitName = splitName[0] + "-" + str(index)
index += 1
newName = splitPath[0] + "/" + newSplitName + splitName[1]
print "newName = " + newName
else:
print "(else) fileName = " + fileName
print "(else) fileName = " + str(type(fileName))
print ""
return fileName
checkExists(newName)
Now it seems that the inner call for checkExists() at the end is not running.
I hope I have been clear in my explanation.
IAmThePiGuy
P.S. I do not want to hear about potential race problems with utime, I know that the files in the source directory will not be accessed by anything else.
Your problem is that, if the file exists, you don't return anything. I think you're intending to use recursion to check the new filename, but you don't return the result of that call. Here's a stab:
def checkExists(fileName, index=0):
print "checkExists(" + fileName + ")"
if exists(fileName):
splitPath = split(newFile)
splitName = splitext(splitPath[1])
newSplitName = splitName[0] + "-" + str(index)
index += 1
newName = splitPath[0] + "/" + newSplitName + splitName[1]
print "newName = " + newName
return checkExists(newName, index) # recurse
else:
print "(else) fileName = " + fileName
print "(else) fileName = " + str(type(fileName))
print ""
return fileName
I also took the liberty of moving the recursive call closer to the generation of newName and removing the global variable and replacing that with recursion as well.
Here's an iterative approach to a similar problem:
def copyfile(path, dstdir, verbose=True, dryrun=False):
"""Copy `path` file to `dstdir` directory incrementing name if necessary."""
filename = os.path.basename(path)
basename, ext = os.path.splitext(filename)
for i in itertools.count(2):
destpath = os.path.join(dstdir, filename)
if not os.path.exists(destpath):
if verbose:
print(path, '->', destpath)
if not dryrun:
shutil.copyfile(path, destpath)
return
# increment filename
filename = "%s_%02d%s" % (basename, i, ext)