473,789 Members | 2,925 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

os.walk help

This script is not recursive... in order to make it recursive, I have to
call it several times (my kludge... hey, it works). I thought os.walk's
sole purpose was to recursively walk a directory structure, no? Also,it
generates the below error during the os.renames section, but the odd
thing is that it actually renames the files before saying it can't find
them. Any ideas are welcomed. If I'm doing something *really* wrong
here, just let me know.

#-------------- ERROR Message ----------------------#

File "/home/rbt/fix-names-1.1.py", line 29, in ?
clean_names(set path)
File "/home/rbt/fix-names-1.1.py", line 27, in clean_names
os.renames(oldp ath, newpath)
File "/usr/local/lib/python2.3/os.py", line 196, in renames
rename(old, new)
OSError: [Errno 2] No such file or directory

#------------- Code -------------------------#

setpath = raw_input("Path to the Directory: ")
bad = re.compile(r'[*?<>/\|\\]')
for root, dirs, files in os.walk(setpath ):
for dname in dirs:
badchars = bad.findall(dna me)
for badchar in badchars:
newdname = dname.replace(b adchar,'-')
if newdname != dname:
newpath = os.path.join(ro ot, newdname)
oldpath = os.path.join(ro ot, dname)
os.renames(oldp ath, newpath)

Jul 18 '05 #1
9 9369
hokieghal99 wrote:
This script is not recursive... in order to make it recursive, I have to
call it several times (my kludge... hey, it works). I thought os.walk's
sole purpose was to recursively walk a directory structure, no? Also,it
generates the below error during the os.renames section, but the odd
thing is that it actually renames the files before saying it can't find
them. Any ideas are welcomed. If I'm doing something *really* wrong
here, just let me know.

#-------------- ERROR Message ----------------------#

File "/home/rbt/fix-names-1.1.py", line 29, in ?
clean_names(set path)
File "/home/rbt/fix-names-1.1.py", line 27, in clean_names
os.renames(oldp ath, newpath)
File "/usr/local/lib/python2.3/os.py", line 196, in renames
rename(old, new)
OSError: [Errno 2] No such file or directory

#------------- Code -------------------------#

setpath = raw_input("Path to the Directory: ")
bad = re.compile(r'[*?<>/\|\\]')
for root, dirs, files in os.walk(setpath ):
for dname in dirs:
badchars = bad.findall(dna me)
for badchar in badchars:
newdname = dname.replace(b adchar,'-')
if newdname != dname:
newpath = os.path.join(ro ot, newdname)
oldpath = os.path.join(ro ot, dname)
os.renames(oldp ath, newpath)


Your code is trying to recurse into the list of directories in 'dirs',
but you are renaming these directories before it can get to them. For
example, if dirs = ['baddir?*', 'gooddir', 'okdir'], you rename
'baddir?*' to 'baddir--' and then os.walk tries to enter 'baddir?*' and
cannot find it. You're better off building a list of paths to rename,
and then renaming them outside of the os.walk scope, or doing something
like...

dirs.remove(dna me)
dirs.append(new dname)

....in your 'if' block.

Peace,
Joe
Jul 18 '05 #2
Joe Francia wrote:
Your code is trying to recurse into the list of directories in 'dirs',
but you are renaming these directories before it can get to them. For
example, if dirs = ['baddir?*', 'gooddir', 'okdir'], you rename
'baddir?*' to 'baddir--' and then os.walk tries to enter 'baddir?*' and
cannot find it. You're better off building a list of paths to rename,
and then renaming them outside of the os.walk scope, or doing something
like...

dirs.remove(dna me)
dirs.append(new dname)

...in your 'if' block.

Peace,
Joe


So, which is better... rename in the os.walk scope or not? The below
code works sometimes at others it produces this error:

ValueError: list.remove(x): x is not in list

setpath = raw_input("Path to the Directory: ")
def clean_names(set path):
bad = re.compile(r'%2 f|%25|%20|[*?<>/\|\\]')
for root, dirs, files in os.walk(setpath ):
for dname in dirs:
badchars = bad.findall(dna me)
for badchar in badchars:
newdname = dname.replace(b adchar,'-')
if newdname != dname:
dirs.remove(dna me)
dirs.append(new dname)
newpath = os.path.join(ro ot, newdname)
oldpath = os.path.join(ro ot, dname)
os.renames(oldp ath, newpath)

Jul 18 '05 #3
hokiegal99 <ho********@hot mail.com> wrote:
Joe Francia wrote:
Your code is trying to recurse into the list of directories in 'dirs',
but you are renaming these directories before it can get to them. For
example, if dirs = ['baddir?*', 'gooddir', 'okdir'], you rename
'baddir?*' to 'baddir--' and then os.walk tries to enter 'baddir?*' and
cannot find it. You're better off building a list of paths to rename,
and then renaming them outside of the os.walk scope, or doing something
like...

dirs.remove(dna me)
dirs.append(new dname)

...in your 'if' block.

Peace,
Joe
So, which is better... rename in the os.walk scope or not? The below
code works sometimes at others it produces this error:

ValueError: list.remove(x): x is not in list


That's strange. It shouldn't be happening. Stick some print statements
in there and see what's going on:
setpath = raw_input("Path to the Directory: ")
def clean_names(set path):
bad = re.compile(r'%2 f|%25|%20|[*?<>/\|\\]')
for root, dirs, files in os.walk(setpath ):
for dname in dirs:
badchars = bad.findall(dna me)
for badchar in badchars:
newdname = dname.replace(b adchar,'-')
if newdname != dname: try: dirs.remove(dna me) except ValueError:
print "%s not in %s" % (dname, dirs)
else: dirs.append(new dname)
newpath = os.path.join(ro ot, newdname)
oldpath = os.path.join(ro ot, dname)
os.renames(oldp ath, newpath)


Note that I'm assuming it's the dirs.remove(dna me) call that's
triggering the ValueError, since there aren't any invocations of
list.remove() anywhere else in your sample code. But I could be wrong;
you should look at the complete exception trace, which will include the
line number at which the exception was thrown.

--
Robin Munn
rm***@pobox.com
Jul 18 '05 #4
Thanks for the tip. That code shows all of the dirs that Python is
complaining about not in the list... trouble is, they *are* in the list.
Go figure. I'd like to try doing the rename outside the scope of
os.walk, but I don't undersdtand how to do this, when I break out of
os.walk and try the rename at a parallel level, Python complains that
variables such as "oldpath" and "newpath" are undefined.

Robin Munn wrote:
hokiegal99 <ho********@hot mail.com> wrote:
Joe Francia wrote:
Your code is trying to recurse into the list of directories in 'dirs',
but you are renaming these directories before it can get to them. For
example, if dirs = ['baddir?*', 'gooddir', 'okdir'], you rename
'baddir?*' to 'baddir--' and then os.walk tries to enter 'baddir?*' and
cannot find it. You're better off building a list of paths to rename,
and then renaming them outside of the os.walk scope, or doing something
like...

dirs.remove( dname)
dirs.append( newdname)

...in your 'if' block.

Peace,
Joe


So, which is better... rename in the os.walk scope or not? The below
code works sometimes at others it produces this error:

ValueError: list.remove(x): x is not in list

That's strange. It shouldn't be happening. Stick some print statements
in there and see what's going on:

setpath = raw_input("Path to the Directory: ")
def clean_names(set path):
bad = re.compile(r'%2 f|%25|%20|[*?<>/\|\\]')
for root, dirs, files in os.walk(setpath ):
for dname in dirs:
badchars = bad.findall(dna me)
for badchar in badchars:
newdname = dname.replace(b adchar,'-')
if newdname != dname:


try:
dirs.remove(dna me)


except ValueError:
print "%s not in %s" % (dname, dirs)
else:
dirs.append(new dname)
newpath = os.path.join(ro ot, newdname)
oldpath = os.path.join(ro ot, dname)
os.renames(oldp ath, newpath)

Note that I'm assuming it's the dirs.remove(dna me) call that's
triggering the ValueError, since there aren't any invocations of
list.remove() anywhere else in your sample code. But I could be wrong;
you should look at the complete exception trace, which will include the
line number at which the exception was thrown.

Jul 18 '05 #5
> This script is not recursive... in order to make it recursive, I have to
call it several times (my kludge... hey, it works). I thought os.walk's
sole purpose was to recursively walk a directory structure, no? Also,it
generates the below error during the os.renames section, but the odd
thing is that it actually renames the files before saying it can't find
them. Any ideas are welcomed. If I'm doing something *really* wrong
here, just let me know.


Try iterating from bottom to top.

See "help(os.walk)" :
walk(top, topdown=True, onerror=None)

...

If optional arg 'topdown' is true or not specified, the triple for a
directory is generated before the triples for any of its
subdirectories
(directories are generated top down). If topdown is false, the triple
for a directory is generated after the triples for all of its
subdirectories (directories are generated bottom up).

...

Jul 18 '05 #6
hokiegal99 <ho********@hot mail.com> wrote:
Thanks for the tip. That code shows all of the dirs that Python is
complaining about not in the list... trouble is, they *are* in the list.
Go figure. I'd like to try doing the rename outside the scope of
os.walk, but I don't undersdtand how to do this, when I break out of
os.walk and try the rename at a parallel level, Python complains that
variables such as "oldpath" and "newpath" are undefined.


Wait, I just realized that you're changing the list *while* you're
iterating over it. That's a bad idea. See the warning at the bottom of
this page in the language reference:

http://www.python.org/doc/current/ref/for.html

Instead of modifying the list while you're looping over it, use the
topdown argument to os.walk to build the tree from the bottom up instead
of from the top down. That way you won't have to futz with the dirnames
list at all:

def clean_names(roo tpath):
bad = re.compile(r'%2 f|%25|%20|[*?<>/\|\\]')
for root, dirs, files in os.walk(rootpat h, topdown=False):
for dname in dirs:
newdname = re.sub(bad, '-', dname)
if newdname != dname:
newpath = os.path.join(ro ot, newdname)
oldpath = os.path.join(ro ot, dname)
os.renames(oldp ath, newpath)

Notice also the use of re.sub to do all the character substitutions at
once. Your code as written would have failed on a filename like "foo*?",
since it always renamed from the original filename: it would have first
done os.renames("foo *?", "foo-?") followed by os.renames("foo *?",
"foo--") and the second would have raised an OSError.

--
Robin Munn
rm***@pobox.com
Jul 18 '05 #7
Robin Munn wrote:
hokiegal99 <ho********@hot mail.com> wrote:
Thanks for the tip. That code shows all of the dirs that Python is
complaining about not in the list... trouble is, they *are* in the list.
Go figure. I'd like to try doing the rename outside the scope of
os.walk, but I don't undersdtand how to do this, when I break out of
os.walk and try the rename at a parallel level, Python complains that
variables such as "oldpath" and "newpath" are undefined.


Wait, I just realized that you're changing the list *while* you're
iterating over it. That's a bad idea. See the warning at the bottom of
this page in the language reference:


Here's a way to modify the list while iterating over it. Too lazy to
generate the sample directory tree, so I suggest that the OP test it :-)

<untested>
def clean_names(roo tpath):
bad = re.compile(r'%2 f|%25|%20|[*?<>/\|\\]')
for root, dirs, files in os.walk(rootpat h):
for index, dname in enumerate(dirs) :
newdname = bad.sub('-', dname)
if newdname != dname:
newpath = os.path.join(ro ot, newdname)
oldpath = os.path.join(ro ot, dname)
try:
os.rename(oldpa th, newpath)
except OSError:
print >> sys.stderr, "cannot rename %r to %r" %
(oldpath, newpath)
else:
dirs[index] = newdname # inform os.walk() about the new
name
</untested>

Peter
Jul 18 '05 #8
This works great! No errors... and it gets dirs that are 8 levels deep
(that's as far down as I've tested). Thanks for the tip! The re.sub
seems to be much faster than the string find/replace approach as well...
I need to read-up more on the documentation of os.walk and re in
general. Thanks again!!!
Robin Munn wrote:
Wait, I just realized that you're changing the list *while* you're
iterating over it. That's a bad idea. See the warning at the bottom of
this page in the language reference:

http://www.python.org/doc/current/ref/for.html

Instead of modifying the list while you're looping over it, use the
topdown argument to os.walk to build the tree from the bottom up instead
of from the top down. That way you won't have to futz with the dirnames
list at all:

def clean_names(roo tpath):
bad = re.compile(r'%2 f|%25|%20|[*?<>/\|\\]')
for root, dirs, files in os.walk(rootpat h, topdown=False):
for dname in dirs:
newdname = re.sub(bad, '-', dname)
if newdname != dname:
newpath = os.path.join(ro ot, newdname)
oldpath = os.path.join(ro ot, dname)
os.renames(oldp ath, newpath)

Notice also the use of re.sub to do all the character substitutions at
once. Your code as written would have failed on a filename like "foo*?",
since it always renamed from the original filename: it would have first
done os.renames("foo *?", "foo-?") followed by os.renames("foo *?",
"foo--") and the second would have raised an OSError.

Jul 18 '05 #9
Could we discuss more about the topdown feature in os.walk? My script is
working fine now, I have no trouble at all with it. I just want to
better understand os.walk in Python 2.3. This is how I understand it as
of today, someone please correct me if I'm wrong:

topdown=False would build a list of filesystem (fs) objects from the
bottom up. The objects at the begining of the list would be the end-most
objects (the leaf nodes) of the fs. When you make changes to that list,
the changes would be from leaf node to os.walk's root instead of root to
leaf node, correct? For example, if I had this dir structure:

dir_a
file_a
dir_b
file_b

My list would look like this:

file_b
dir_b
file_a
dir_a

And, if I made changes to the list and commited those changes to the fs
then there would be no problems because of the order in which the
changes are made. Is this a proper way to describe topdown=False in
os.walk? Or in other words, our list would be static (one change would
not impact another), where if topdown=True our list would be dynamic
(one change could impact another).

Thanks for the help!!!


Robin Munn wrote:
Wait, I just realized that you're changing the list *while* you're
iterating over it. That's a bad idea. See the warning at the bottom of
this page in the language reference:

http://www.python.org/doc/current/ref/for.html

Instead of modifying the list while you're looping over it, use the
topdown argument to os.walk to build the tree from the bottom up instead
of from the top down. That way you won't have to futz with the dirnames
list at all:

def clean_names(roo tpath):
bad = re.compile(r'%2 f|%25|%20|[*?<>/\|\\]')
for root, dirs, files in os.walk(rootpat h, topdown=False):
for dname in dirs:
newdname = re.sub(bad, '-', dname)
if newdname != dname:
newpath = os.path.join(ro ot, newdname)
oldpath = os.path.join(ro ot, dname)
os.renames(oldp ath, newpath)

Notice also the use of re.sub to do all the character substitutions at
once. Your code as written would have failed on a filename like "foo*?",
since it always renamed from the original filename: it would have first
done os.renames("foo *?", "foo-?") followed by os.renames("foo *?",
"foo--") and the second would have raised an OSError.


Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
1427
by: Tom | last post by:
I need help to implement the following task in Java and any XML API but preferably JDOM. I am a total newbie to this. I have a DocBook document, for example: <chapter> <title>Title</title> <para> Text </para> <mediaobject>
6
1469
by: Ivan Shevanski | last post by:
To continue with my previous problems, now I'm trying out classes. But I have a problem (which I bet is easily solveable) that I really don't get. The numerous tutorials I've looked at just confsed me.For intance: >>>class Xyz: .... def y(self): .... q = 2 .... >>>Xyz.y() Traceback (most recent call last):
22
5405
by: delraydog | last post by:
It's quite simple to walk to the DOM tree going forward however I can't figure out a nice clean way to walk the DOM tree in reverse. Checking previousSibling is not sufficient as the previousSibling could be a node which has childNodes and therefore the 'true' previousSibling would be the *deepest* lastChild of the previousSibling... For example, given this graph: 1 myAnchor nodeType 1 2 myAnchorText1 nodeType 3
6
5921
by: Bruce | last post by:
Hi all, I have a question about traversing file systems, and could use some help. Because of directories with many files in them, os.walk appears to be rather slow. I`m thinking there is a potential for speed-up since I don`t need os.walk to report filenames of all the files in every directory it visits. Is there some clever way to use os.walk or another tool that would provide functionality like os.walk except for the listing of the...
45
3957
nemisis
by: nemisis | last post by:
Hi Everyone I have am doing an object oriented C++ program and I have no idea as to how start it................. I am not that good at coding so i tried and made an overview of what the main driver should look like main{
2
4022
by: gregpinero | last post by:
In the example from help(os.walk) it lists this: from os.path import join, getsize for root, dirs, files in walk('python/Lib/email'): print root, "consumes", print sum(), print "bytes in", len(files), "non-directory files" if 'CVS' in dirs: dirs.remove('CVS') # don't visit CVS directories
8
2320
by: inFocus | last post by:
Hello, I am new to python and wanted to write something for myself where after inputing two words it would search entire drive and when finding both names in files name would either copy or move thoe files to a specified directory. But couple of attempts did not work as desired this is one of them. Could someone help fix it or maybe give a better example.
0
2039
by: Jeff McNeil | last post by:
Your args are fine, that's just the way os.path.walk works. If you just need the absolute pathname of a directory when given a relative path, you can always use os.path.abspath, too. A couple more examples that may help, using os.walk: .... for j in i + i: .... print os.path.join(i, j) .... /var/log/apache2
4
2470
by: Jeff Nyman | last post by:
Greetings all. I did some searching on this but I can't seem to find a specific solution. I have code like this: ========================================= def walker1(arg, dirname, names): DC_List.append((dirname,'')) os.path.walk('\\\\vcdcflx006\\Flex\\Sites', walker1, 0)
0
9666
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9511
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10410
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9020
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6769
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5418
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5551
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3701
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2909
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.