views:

66

answers:

5

I have a file containing a file "dir.txt" with the below data:

/home/abc/a.txt
/home/abc/b.txt
/home/xyz/test
/home/xyz/test/d.txt
/home/xyz/test/e.txt
/home/xyz/test/f.txt
/home/xyz
/home/xyz/g.txt

I want to parse the file and get the output like

/home/abc/a.txt
          b.txt
/home/xyz/test/d.txt
               e.txt
               f.txt
/home/xyz/g.txt

Using python, basically need to print the content in a tree format. How would I process it?

+4  A: 

you need to use os.path.split on every path, find the first dirname and print path as it is. find it length and print so many spaces before next basename, on change of the dirname repeat as before.

>>> import os.path    
>>> olddir = None
>>> for name in open('input.txt'):
    dirname, fname = os.path.split(name)
    if olddir != dirname:
        prefix = ' ' * (len(dirname) +1)
        olddir = dirname
        print(name)
    else:
        print(prefix + fname)


/home/abc/a.txt
          b.txt
/home/xyz/test/d.txt
               e.txt
               f.txt
/home/xyz/g.txt
SilentGhost
+1 don't forget to breath :)
gnibbler
+2  A: 

Try this:

import os.path

txt = """/home/abc/a.txt
/home/abc/b.txt
/home/xyz/test/d.txt
/home/xyz/test/e.txt
/home/xyz/test/f.txt
/home/xyz/g.txt"""

last_d = ''
for l in txt.split('\n'):
    (d, n) = os.path.split(l)
    if d == last_d:
        d = ' ' * len(last_d)
    else:
        last_d = d
    print('%s/%s' % (d, n))
Michał Niklas
testing, testing, testing :)
SilentGhost
this will not work is the lines are not sorted.
ghostdog74
@ghostdog74: there was no indication in the answer that it might be the case, even if it is so, adding `sorted` to `for` clause is trivial.
SilentGhost
I've changed the source a little bit!!
Panther24
A: 
>>> filenames="""/home/abc/a.txt
... /home/abc/b.txt
... /home/xyz/test/d.txt
... /home/xyz/test/e.txt
... /home/xyz/test/f.txt
... /home/xyz/g.txt""".split()
>>> 
>>> import os
>>> prev=''
>>> for n in filenames:
...     path,name = os.path.split(n)    
...     if path==prev:
...         print " "*len(prev)+" "+name
...     else:
...         print n
...         prev=path
... 
/home/abc/a.txt
          b.txt
/home/xyz/test/d.txt
               e.txt
               f.txt
/home/xyz/g.txt
gnibbler
+2  A: 

@Op,use a dictionary. Use the paths as the key and the file names as values

from collections import defaultdict
d=defaultdict(list)
for line in open("file"):
    line=line.strip()
    s='/'.join(line.split("/")[:-1])
    d[s].append(line.split("/")[-1])

for i,j in d.iteritems():
    print i,j

output

$ ./python.py
/home/xyz ['g.txt']
/home/xyz/test ['d.txt', 'e.txt', 'f.txt']
/home/abc ['a.txt', 'b.txt']

Do the formatting as described by the answers others had posted.

ghostdog74
A: 

This is an alternate take that offers a different output, just in case the OP would prefer this format:

/home/abc/a.txt
          b.txt
      xyz/test/d.txt
               e.txt
               f.txt
          g.txt

then this code:

import os

def pretty_printer(seq_of_strings):
    previous_line= ''
    for line in seq_of_strings:
        last_sep= os.path.commonprefix([previous_line, line]).rfind(os.path.sep)+1
        yield ' '*last_sep + line[last_sep:]
        previous_line= line

might do the trick.

Should the OP comment that they don't need it at all, I'll delete this answer.

ΤΖΩΤΖΙΟΥ