19

I have a dir structure like the following:

[me@mypc]$ tree .
.
├── set01
│   ├── 01
│   │   ├── p1-001a.png
│   │   ├── p1-001b.png
│   │   ├── p1-001c.png
│   │   ├── p1-001d.png
│   │   └── p1-001e.png
│   ├── 02
│   │   ├── p2-001a.png
│   │   ├── p2-001b.png
│   │   ├── p2-001c.png
│   │   ├── p2-001d.png
│   │   └── p2-001e.png

I would like to write a python script to rename all *a.png to 01.png, *b.png to 02.png, and so on. Frist I guess I have to use something similar to find . -name '*.png', and the most similar thing I found in python was os.walk. However, in os.walk I have to check every file, if it's png, then I'll concatenate it with it's root, somehow not that elegant. I was wondering if there is a better way to do this? Thanks in advance.

clwen
  • 20,004
  • 31
  • 77
  • 94

4 Answers4

18

For a search pattern like that, you can probably get away with glob.

from glob import glob
paths = glob('set01/*/*.png')
moooeeeep
  • 31,622
  • 22
  • 98
  • 187
Michael Mior
  • 28,107
  • 9
  • 89
  • 113
11

You can use os.walk to traverse the directory tree. Maybe this works?

import os

for dpath, dnames, fnames in os.walk("."):
  for i, fname in enumerate([os.path.join(dpath, fname) for fname in fnames]):
    if fname.endswith(".png"):
      #os.rename(fname, os.path.join(dpath, "%04d.png" % i))
      print "mv %s %s" % (fname, os.path.join(dpath, "%04d.png" % i))

For Python 3.4+ you may want to use pathlib.glob() with a recursive pattern (e.g., **/*.png) instead:

moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • 2
    I would consider using `if file.endswith(".png"):` instead of that `rsplit()` (which will do more work than is really necessary). – Greg Hewgill Nov 24 '11 at 08:28
1

Check out genfind.py from David M. Beazley.

# genfind.py
#
# A function that generates files that match a given filename pattern

import os
import fnmatch

def gen_find(filepat,top):
    for path, dirlist, filelist in os.walk(top):
        for name in fnmatch.filter(filelist,filepat):
            yield os.path.join(path,name)

# Example use

if __name__ == '__main__':
    lognames = gen_find("access-log*","www")
    for name in lognames:
        print name
Michael Mior
  • 28,107
  • 9
  • 89
  • 113
Spencer Rathbun
  • 14,510
  • 6
  • 54
  • 73
-2

These days, pathlib is a convenient option.

Michael Mior
  • 28,107
  • 9
  • 89
  • 113
Magnus Lyckå
  • 336
  • 2
  • 8