
xinput = "$ cd /
$ ls
dir btsgrbd
3868 cprq.fmm
dir gcbpcf
dir hfm
324644 lthcng.gnf
133181 nblfzrb.mrr
140568 sfrbjmmh.jnj
dir tfsh
dir vlsqgrw
202279 vmpgqbcd
$ cd btsgrbd
$ ls
dir cmfdm
dir cqd
dir gvwvs
dir nblfzrb
dir nfm
293979 qwnml.bqn
159220 sdwnsgwv.mjm
327978 vzgwwjq.zbp
155479 zvspnvfr.zbc
$ cd cmfdm
$ ls
dir gldnjj
dir vhf
$ cd gldnjj
$ ls
dir dvght
93750 lwvtzd.pws
176529 sdwnsgwv.mjm
100111 vmpgqbcd
$ cd dvght
$ ls
dir tfbzq
$ cd tfbzq
$ ls
276592 tcghw.srg
$ cd ..
$ cd ..
$ cd ..
$ cd vhf
$ ls
240217 hfm.rfp
dir nblfzrb
$ cd nblfzrb
$ ls
160378 jhc
$ cd ..
$ cd ..
$ cd ..
$ cd cqd
$ ls
305358 bnddfgrb
dir dwqncqp
dir hnnfdtbh
dir jhc
dir nblfzrb
327762 scnm.qbf
165080 vmpgqbcd
190041 vzgwwjq.zbp
dir zwv
$ cd dwqncqp
$ ls
122570 slpgmhv
278461 zlnbcwr
$ cd ..
$ cd hnnfdtbh
$ ls
334830 gfprhn.rjj
$ cd ..
$ cd jhc
$ ls
179593 fgb.btb
$ cd ..
$ cd nblfzrb
$ ls
dir clbcgvhc
dir jhc
dir lsrnz
dir mctd
$ cd clbcgvhc
$ ls
285825 hnn
238272 nblfzrb.wvr
$ cd ..
$ cd jhc
$ ls
99731 nblfzrb.svz
$ cd ..
$ cd lsrnz
$ ls
257843 fsthnpmd
$ cd ..
$ cd mctd
$ ls
278117 zlnbcwr
$ cd ..
$ cd ..
$ cd zwv
$ ls
40349 jhc
dir pqwml
173804 sdwnsgwv.mjm
$ cd pqwml
$ ls
193573 hbzvzwpr
$ cd ..
$ cd ..
$ cd ..
$ cd gvwvs
$ ls
dir gjslw
dir gwz
dir ljvrjp
dir sltlpb
dir vbsnq
$ cd gjslw
$ ls
dir gzbm
$ cd gzbm
$ ls
dir fst
dir gpjz
dir gzd
dir hfm
$ cd fst
$ ls
99806 mqpg
$ cd ..
$ cd gpjz
$ ls
dir dnsvsp
218828 jhc.dfd
$ cd dnsvsp
$ ls
dir vmdbpwj
dir zvspnvfr
$ cd vmdbpwj
$ ls
258373 jhc
$ cd ..
$ cd zvspnvfr
$ ls
18241 vzgwwjq.zbp
$ cd ..
$ cd ..
$ cd ..
$ cd gzd
$ ls
20383 chdfwj
63309 prrlv.rvn";

xlines = StringSplit[xinput, "\n" ];

(* process each line one at a time. and built list of path first. then turn the paths into a tree. *)

(* each element is again a list, of dir/file names *)
xpaths = {};

xLinePartsList =  Map[ StringSplit , xlines ];
(* e.g. each is like this *)
(* { "$", "cd", "e"} *)
(* { "8033020" "d.log" } *)

(* a list of dir names *)
curDir = {};

sizeLookupTable = Association[];

dirTree = Association[];

(* built a list of path, the xpaths *)
Map[Function[{xx},
  If[xx[[1]] === "$",
   (*line is a cmd*)
   (If[xx[[2]] === "cd",
    (* is cd*)
     If[xx[[3]] === "..", (curDir = Drop[curDir, -1]), (AppendTo[curDir, xx[[3]]])];
    AppendTo[xpaths, curDir], (*it is ls*)
    Null]),
(*line is not a cmd. it means it's size and filename, or dir and filename.
if dir, ignore. if file, add to sizeLookupTable.*)
If[ xx[[1]] === "dir" ,
Null,
 With[{fsize = xx[[1]], filename = xx[[2]], filepath = (Append[curDir, xx[[2]]]) },
    AppendTo[xpaths, filepath];
    AssociateTo[sizeLookupTable, filepath -> fsize]]]
]], xLinePartsList];

(* ssss---------------------------------------------------  *)

(* built a tree, a nested dict, by going thru xpaths *)

Map[ Function[{x}, expr]  , xpaths ]

(* dirTree[key][key][key] = val *)

(* ssss---------------------------------------------------  *)

(* problem, turn this *)
onePath = { "a" , "b" , "c"};

(* into this *)
xx=
Association[ "a" ->
 Association[ "b" ->
  Association[ "c" -> 1 ]]
]

(* ssss---------------------------------------------------  *)

(*
solution
use a pattern matching to turn
{ "a" , "b" , "c"}
into
Association[ "a" -> Association[ "b" -> Association[ "c" -> 1 ]] ]
or
xx["a"]["b"]["c"] = 1
*)

{ x_, y__ } //. (dirTree[x] = Association[  ])

AssociateTo[ dirTree, root -> xx ]
Fold[ f, { "a" , "b" , "c"} ]
f[f[f["a", "b"], "c"], "d"]

Fold[
 Function[ {x,y}, x[y] = Association[] ],
 dirTree,
 { "a" , "b" , "c"} ]

Fold[
 Function[ {x,y}, ReleaseHold[ x[y] ] = Association[]; Hold[ x[y] ] ],
 { dirTree, "a" , "b" , "c"} ]

ReleaseHold[ Hold[ Hold [ 1+2]] ]

x[y] = Association[]
AssociateTo[x, y -> Association[]]

Map[
  Function[
    {x},
    AssociateTo[ dirTree, x -> 0 ]]  ,
 xxinput ]

AssociateTo[ dirTree, x -> 0 ]
AssociateTo[ AssociateTo[ dirTree, a -> 0 ], x -> 0 ]
AssociateTo[ AssociateTo[ AssociateTo[ dirTree, a -> 0 ], b -> 0 ], x -> 0 ]

AssociateTo[ dirTree, x -> 0 ]
dirTree[x] = 0

dirTree["a"]["b"]["c"] = 1
