0

I'm having a little brainfreeze here.

I want to add an index to the files and directories. I've tried so many different solutions that I finally decided to turn to the community for some pointers.

When traversing the tree directory A-1.1 is assigned index of 2 instead of 1.1, as it is the second directory os.walk enters.

I am doing this to save our secretaries at work countless hours of renaming files/directories. Any help much appreciated.

If someone wants to give it a try here's the test directory tree :

https://drive.google.com/open?id=1EoBzVPFOvixMlCdWWlUgucMd5zunI20U

As I was told download takes ages, here's zipped version :

https://drive.google.com/open?id=1I-1LKk2FRIVm9Tp2I9bYQOCOemV07jQr

The embarrassing code:

import os
rootDir = "/.../root"
rootIndex = 1

for dirName, subdirList, fileList in sorted(os.walk(rootDir)):

   subindex = 1

   print(f'DIR : {rootIndex} - {dirName}')

   for fname in fileList:
       print(f'file :: {rootIndex}.{subindex} - {fname}')
       subindex = subindex + 1

### This cannot work properly as it increases the rootIndex whenever it encounters empty dir
   if not subdirList:
       print(f'End')
       rootIndex = rootIndex + 1

The tree looks like this, with hardcoded desired result to keep track of it.

├── A-1
│   ├── A-1.1
│   │   ├── file-A-1.1.1.txt
│   │   ├── file-A-1.1.2.txt
│   │   ├── file-A-1.1.3.txt
│   │   ├── file-A-1.1.4.txt
│   │   └── file-A-1.1.5.txt
│   ├── A-1.2
│   │   ├── file-A-1.2.1.txt
│   │   ├── file-A-1.2.2.txt
│   │   ├── file-A-1.2.3.txt
│   │   ├── file-A-1.2.4.txt
│   │   └── file-A-1.2.5.txt
│   └── A-1.3
│       ├── A-1.3.1
│       │   ├── file-A-1.3.1.1.txt
│       │   ├── file-A-1.3.1.2.txt
│       │   ├── file-A-1.3.1.3.txt
│       │   ├── file-A-1.3.1.4.txt
│       │   └── file-A-1.3.1.5.txt
│       └── A-1.3.2
│           ├── file-A-1.3.2.1.txt
│           ├── file-A-1.3.2.2.txt
│           ├── file-A-1.3.2.3.txt
│           ├── file-A-1.3.2.4.txt
│           └── file-A-1.3.2.5.txt
└── B-2
├── B-2.1
│   ├── file-B-2.1.1.txt
│   ├── file-B-2.1.2.txt
│   ├── file-B-2.1.3.txt
│   ├── file-B-2.1.4.txt
│   └── file-B-2.1.5.txt
└── B-2.2
├── B-2.2.1
│   ├── file-B-2.2.1.1.txt
│   ├── file-B-2.2.1.2.txt
│   ├── file-B-2.2.1.3.txt
│   ├── file-B-2.2.1.4.txt
│   └── file-B-2.2.1.5.txt
├── B-2.2.2
│   ├── file-B-2.2.2.1.txt
│   ├── file-B-2.2.2.2.txt
│   ├── file-B-2.2.2.3.txt
│   ├── file-B-2.2.2.4.txt
│   └── file-B-2.2.2.5.txt
├── file-B-2.2.3.txt
├── file-B-2.2.4.txt
├── file-B-2.2.5.txt
├── file-B-2.2.6.txt
└── file-B-2.2.7.txt
yoK0
  • 325
  • 1
  • 3
  • 17
  • Maybe store the indexes in a list and then covert the list to string with `''.join(map(lambda x: str(x), indexes))` – Maxxik CZ Dec 19 '19 at 14:10
  • I was combining the index when diving in the tree but then when I got back to root and dive into folder B it was all messed up. Cant figure out how to preserve the index for each level. – yoK0 Dec 19 '19 at 14:13
  • so let's say you have a list of indexes `[2, 4]` meaning you are currently pointing to the fourth file in the second root folder. After the end just pop the last value from the list with `indexes.pop(-1)` and then increase the now last index and enter another folder `indexes[-1] += 1`. Would this work? – Maxxik CZ Dec 19 '19 at 14:17
  • Yes, that makes sense. The problem Im facing is how do I determine when to pop the value from the list. – yoK0 Dec 19 '19 at 14:23
  • I found [this](https://stackoverflow.com/questions/9727673/list-directory-tree-structure-in-python) with one google search. Is it what you're looking for? – Maxxik CZ Dec 19 '19 at 15:25
  • Seen it already. I've done many google search and tried to put some pieces together to make the indexing works, yet still struggling. Playing with the list solution right now, not looking good, yet. It seems simple in theory tho. – yoK0 Dec 19 '19 at 15:29
  • BTW, I can traverse the tree just fine, whether with os.walk or with recursion the indexing is the problem. – yoK0 Dec 19 '19 at 15:31
  • @MaxxikCZ I've added link to test directory tree if you want to give it a try. – yoK0 Dec 19 '19 at 15:36
  • @yoK0. The directory tree is taking some time to download, and isn't the best way to send secure information. Can you provide some python code that generates the tree? – mathew gunther Dec 19 '19 at 15:50
  • @mathewgunther it's just few directories with empty text files. I do not have python code to generate the tree with this names. Frankly, if I had a code to do this, I'd had a code to index it. Wouldn't I ;) – yoK0 Dec 19 '19 at 16:08
  • @yoko. In that case, let me see if I can generate the directory structure above with some code – mathew gunther Dec 19 '19 at 16:14
  • @yoK0 I've tried something myself and I've come to the conclusion, that this task is not really easy with `os.walk`. I don't know whether there are any other alternatives. But what I can suggest is that you can check the level of how deep you are with a simple function like this: `len(path.split('/'))`. You could then check whether the last path was of a higher or less indent and act accordingly. Hope it helps! – Maxxik CZ Dec 19 '19 at 21:06
  • @MaxxikCZ not so easy right. Doesn't seem so hard at first. Im playing now with recursion and os.listdir. – yoK0 Dec 19 '19 at 21:34
  • @yoK0 finally found a solution, in a morning train. Sorry if it doesn't work for you. Best of luck! – Maxxik CZ Dec 20 '19 at 06:12

2 Answers2

0

This can be solved by using your own recursive function with python list dir

def list_files(dir_path, indexes=[]):
    index_str = ".".join(indexes)
    print(f'DIR : {index_str} - {dir_path}')
    dir_elements = os.listdir(dir_path)

    files_list = []
    dirs_list  = []

    for f in dir_elements:
        if os.path.isdir(os.path.join(dir_path, f)):
            dirs_list.append(os.path.join(dir_path, f))
        else:
            files_list.append(f)

    findex = 1
    for file in sorted(files_list):
        findex_str = ".".join(indexes + [str(findex)])
        print(f'file :: {findex_str} - {file}')
        findex += 1

    dindex = 1
    for dir in sorted(dirs_list):
        list_files(dir, indexes + [str(dindex)])
        dindex += 1
JoshKisb
  • 742
  • 7
  • 9
  • 1
    Nicely done. Nearly working correctly Does not account for the files and directories being within the same folder though. Because you keep files and dirs separate with their own index it won't be easily done with this code base. I have a bad feeling it may require total rebuild. Anyways, i'll have a go and much appreciated. – yoK0 Dec 20 '19 at 11:42
  • yeah doing it like this allows for you to easily customize as much as you need :) – JoshKisb Dec 20 '19 at 13:45
0

So I finally found a solution that seems to work. Tested on android, don't know about windows.

import os

def indent(s):
    return len(s.split('/'))

path = 'projects/'

indexes = []
last = ''
for name, dl, fl in os.walk(path):
    # has to be printed BEFORE the index manipulation
    # here you can also rename the files with joining the indexes list like this:
    # '-'.join(map(lambda x: str(x)))
    print 'files:{}|{}\t{}'.format(len(fl), ' '.join(map(lambda x: str(x), indexes)), name)

    if dl:
        indexes.append(1)
    elif indent(name) == indent(last):
        indexes[-1] += 1
    else:
        repeats = abs(indent(name) - indent(last))
        for i in range(repeats):
            indexes.pop(-1)
        try:
            indexes[-1] += 1
        except IndexError:
            break

    last = name
print 'done'
Maxxik CZ
  • 314
  • 2
  • 9
  • It doesn't reset the index correctly when jumping from A-1 to B-2. ` files:0|1 3 3 C:\...\Desktop\TEST\B-2 ` – Good job nevertheless – yoK0 Dec 20 '19 at 11:24
  • Oh, so in the `else` branch try to pop for every difference in the indent. Should work then. I edited the answer – Maxxik CZ Dec 20 '19 at 17:38