|
Programming Python Authors: Lutz M. Published year: 2004 Pages: 63/270 |
7.3. Fixing DOS FilenamesThe heart of the prior script was findFiles , a function that knows how to portably collect matching file and directory names in an entire tree, given a list of filename patterns. It doesn't do much more than the built-in find.find call, but it can be augmented for our own purposes. Because this logic was bundled up in a function, though, it automatically becomes a reusable tool. For example, the next script imports and applies findFiles , to collect all filenames in a directory tree, by using the filename pattern * (it matches everything). I use this script to fix a legacy problem in the book's examples tree. The names of some files created under MS-DOS were made all uppercase; for example, spam.py became SPAM.PY somewhere along the way. Because case is significant both in Python and on some platforms, an import statement such as import spam will sometimes fail for uppercase filenames. To repair the damage everywhere in the thousand-file examples tree, I wrote and ran Example 7-6. It works like this: for every filename in the tree, it checks to see whether the name is all uppercase and asks the console user whether the file should be renamed with the os.rename call. To make this easy, it also comes up with a reasonable default for most new namesthe old one in all-lowercase form. Example 7-6. PP3E\PyTools\fixnames_all.py
As before, the findFiles function returns a list of simple filename lists, representing the expansion of all patterns passed in (here, just one result list, for the wildcard pattern * ). [*] For each file and directory name in the result, this script's convertOne function prompts for name changes; an os.path.split and an os.path.join call combination portably tacks the new filename onto the old directory name. Here is a renaming session in progress on Windows:
C:\temp\examples> python %X%\PyTools\fixnames_all.py Using Python find 1 => .\.cshrc 2 => .\LaunchBrowser.out.txt 3 => .\LaunchBrowser.py ... ...more deleted... ... 218 => .\Ai 219 => .\Ai\ExpertSystem 220 => .\Ai\ExpertSystem\TODO Convert dir=.\Ai\ExpertSystem file=TODO? (yY)n 221 => .\Ai\ExpertSystem\_ _init_ _.py 222 => .\Ai\ExpertSystem\holmes 223 => .\Ai\ExpertSystem\holmes\README.1ST Convert dir=.\Ai\ExpertSystem\holmes file=README.1ST? (yY)y Type new file name (enter=readme.1st): Renamed: .\Ai\ExpertSystem\holmes\README.1st to: .\Ai\ExpertSystem\holmes\readme.1st Press enter to continue 224 => .\Ai\ExpertSystem\holmes\README.2ND Convert dir=.\Ai\ExpertSystem\holmes file=README.2ND? (yY)y Type new file name (enter=readme.2nd): readme-more Renamed: .\Ai\ExpertSystem\holmes\README.2nd to: .\Ai\ExpertSystem\holmes\readme-more Press enter to continue ... ...more deleted... ... 1471 => .\todos.py 1472 => .\tounix.py 1473 => .\xferall.linux.csh Converted 2 files, visited 1473 This script could simply convert every all-uppercase name to an all-lowercase equivalent automatically, but that's potentially dangerous (some names might require mixed case). Instead, it asks for input during the traversal and shows the results of each renaming operation along the way. 7.3.1. Rewriting with os.path.walkNotice, though, that the pattern-matching power of the find.find call goes completely unused in this script. Because this call must always visit every file in the tree, the os.path.walk interface we studied in Chapter 4 would work just as well and avoids any initial pause while a filename list is being collected (that pause is negligible here but may be significant for larger trees). Example 7-7 is an equivalent version of this script that does its tree traversal with the walk callbacks-based model. Example 7-7. PP3E\PyTools\fixnames_all2.py
This version does the same job but visits one extra file (the topmost root directory), and it may visit directories in a different order ( os.listdir results are unordered). Both versions run in similar time for the examples directory tree on my computer. [*] We'll revisit this script, as well as the fixeoln line-end fixer , in the context of a general tree-walker class hierarchy later in this chapter.
|
|
Programming Python Authors: Lutz M. Published year: 2004 Pages: 63/270 |