Converting filenames with embedded backslashes to directory tree

terminalzip

I recently extracted a ZIP file that I expected to contain a path hierarchy but turned out to be a flat archive of files with backslashes in the filenames. So I ended up with something like:

$ ls -1d ./*
SomeFile.txt
Foo\OtherFile.png
Bar\Baz\Faz\foo.txt

All of these are just siblings in the same single directory. In my actual case, there are several hundred files, so making the directories and moving things by hand would be tedious at best.

My current plan is to write a small Python program to put them all where they belong, but I was wondering, is there a quicker easier way to do it from the command line?

Best Answer

Python to the rescue!

#!/usr/bin/env python
import sys, os, os.path

def treeify(filenames):
    for fn in filenames:
        parts = fn.split("\\")
        pathparts = parts[:-1]
        basename = parts[-1]
        path = ensurepath(pathparts)
        os.rename(fn, os.path.join(path, basename))

def ensurepath(parts):
    if len(parts) == 0:
        return "."
    path = os.path.join(*parts)
    if not os.path.exists(path):
        os.makedirs(path)
    return path

if __name__ == "__main__":
    treeify(sys.argv[1:])

Invoked like:

$ ~/scripts/tree.py *