Create a flat file and directory structure

Hi All,

is there any work around to generate the file and directory structure like below at left side at Output? and exclude all file except .abc .txt

Current Directory structure

|-------------files
|---------------Share
|-----------------dir1
|-----------------dir2
|-----------------dir3
|-----------------dir4
|-----------------dir5
|-----------------dir6
|-----------------dir7
|-----------------dir8
|-------------------IMG
|---------------------IMG001
|---------------------IMG002
|-----------------------1234.abc
|-----------------------abcd.txt
|-------------------00001
|---------------------IMG
|-----------------------IMG1
|-----------------------IMG2
|-------------------Sample
|---------------------hello
|-----------------------prod
|-------------------------NAD
|---------------------------NAT
|-------------------------TEXT
|---------------------------TEXTILE1
|---------------------00002
|-----------------------IMAG
|-------------------------IMAG1
|-------------------------IMAG2
|-----------------dir9
|-----------------dir10
|-----------------dir11

print Output file look like this

1 files    
1.1 Share
1.1.1 dir1
1.1.2 dir2    
1.1.3 dir3
1.1.4 dir4
1.1.5 dir5
1.1.6 dir6
1.1.7 dir7
1.1.8 dir8
1.1.8.1 IMG
1.1.8.1.1 IMG001    
1.1.8.1.2 IMG002    
1.1.8.1.2.1 1234.abc        
1.1.8.1.2.2 abcd.txt    
1.1.8.2 00001            
1.1.8.2.1 IMG                
1.1.8.2.1.1    IMG1            
1.1.8.2.1.2    IMG2            
1.1.8.3    Sample                
1.1.8.3.1 hello                
1.1.8.3.1.1    prod            
1.1.8.3.1.1.1 NAD            
1.1.8.3.1.1.1.1 NAT            
1.1.8.3.1.1.1.2    TEXT        
1.1.8.3.1.1.2.2.1 TEXTILE1    
1.1.8.3.2 00002                
1.1.8.3.2.1 IMAG            
1.1.8.3.2.1.1 IMAG1        
1.1.8.3.2.1.2 IMAG2        
1.1.9 dir9                
1.1.10 dir10            
1.1.11 dir11            

Thank you

Is this a one-time or re-occuring task? If is just a one time job, it is easier to just create the directories manually than writing a script for parsing this input file.
The -p switch of mkdir might come handy when creating the directories.

My apologies, I mean File and Directory Structure is my current structure directory, but i want to generate a full path of file and directory structure and print to a file, not to create a directory

thanks for response

---------- Post updated 02-21-13 at 10:19 AM ---------- Previous update was 02-20-13 at 06:43 PM ----------

is this possible for unix?

This comes close, only issue is unix sorts alphabetically so order is
dir1
dir11
dir12
dir2

find ./files \( -type d -o -name "*.abc" -o -name "*.txt" \) -print | awk '
function ppath(p, f, c) {
   s=index(f, "/");
   if (!p) return ppath(substr(f,1,s-1), substr(f,s+1), "");
   if (!s) pf=p"/"f;
   else pf=p"/"substr(f,1,s-1);
   if (!(pf in found)) {
      found[p]++;
      found[pf]=0
   }
   if (!s) return (c?c".":"") found[p] " " f
   return ppath(pf, substr(f, s+1), (c?c".":"") found[p])
}
{ print ppath("", $0, "") }

output:

1 files
1.1 Share
1.1.1 dir1
1.1.2 dir10
1.1.3 dir11
1.1.4 dir2
1.1.5 dir3
1.1.6 dir4
1.1.7 dir5
1.1.8 dir6
1.1.9 dir7
1.1.10 dir8
1.1.10.1 00001
1.1.10.1.1 IMG
1.1.10.1.1.1 IMG1
1.1.10.1.1.2 IMG2
1.1.10.2 IMG
1.1.10.2.1 IMG001
1.1.10.2.2 IMG002
1.1.10.2.2.1 1234.abc
1.1.10.2.2.2 abcd.txt
1.1.10.3 Sample
1.1.10.3.1 00002
1.1.10.3.1.1 IMAG
1.1.10.3.1.1.1 IMAG1
1.1.10.3.1.1.2 IMAG2
1.1.10.3.2 hello
1.1.10.3.2.1 prod
1.1.10.3.2.1.1 NAD
1.1.10.3.2.1.1.1 NAT
1.1.10.3.2.1.2 TEXT
1.1.10.3.2.1.2.1 TEXTILE1
1.1.11 dir9

---------- Post updated at 02:49 PM ---------- Previous update was at 01:49 PM ----------

Another solution without recursion:

find ./files \( -type d -o -name "*.abc" -o -name "*.txt" \) -print | awk '{
  c=split($0,v,"/");
  f=v[1];
  for(i=2;i<=c;i++)  {
      if(!(f in P)) P[f]=0;
      if(!(f"/"v in P)) P[f]++;
      P[f"/"v];
      printf "%s",P[f] (i<c?".":"")
      f=f"/"v
  }
  print " " v[i-1];
}'

very appreciate the scripts, sir could you please explain a little bit more whats going on of your script?

thank again.

The find statement produces a list of files and directories that match the criteria (directory or name ends in .txt or .abc) something like this:

./files
./files/Share
./files/Share/dir1
./files/Share/dir10
...etc

Each directory component is broken out and put into a array (found[] in first script and v[] in second)
Each element in the array counts how many children sit below it

v[.]=1
v[./files]=1
v[./files/Share]=11
v[./files/Share/dir8]=3
...

Now if a new directory or file ./files/Share/dirX is processed the count in v[./files/Share] will be incremented to 12 because no entry exists for v[./files/Share/dirX] this allows the output of 1.12.1 dirX to be printed.

Thank so much for your help sir.

---------- Post updated 02-22-13 at 09:11 AM ---------- Previous update was 02-21-13 at 02:15 PM ----------

Sir have a question, what about exclude some folder and their succeeding sub directory, I tried to add something like this:

\( -type d -o -name "*.dat" -o -name "*.txt" -o ! -name "warcraft" \)

is not working, is there any work around?

need to exclude directory and their succeeding subdirectory.

Thanks

Actually, find doesn't even guarantee that. No assumptions can be made.

For some reason, this little problem interested me (not the sorting, but generating the indices). Borrowing your find , here's my attempt at a recursive AWK solution:

find ./files \( -type d -o -name "*.abc" -o -name "*.txt" \) | awk -F'/+[^/]' '
function ppath(n,b,i,s) {
    do {
        s = b "." ++i
        print s " " $0
        if (getline != 1) exit
        if (n < NF) ppath(NF, s)
    } while (n == NF)
}
NR == 1 { print 1 " " $0 }
NR == 2 { ppath(NF, 1) }'

My once a year perl diversion:

perl -lpaF/+ -e '$b=$#F if $.==1; $n=$#F-$b; $a[$n]=0 if $n>$o; $a[$o=$n]++; printf "%s ", join(".", @a[0..$n])'

Regards,
Alister

Thanks for the response, I will try to run your script and update you soon.

thanks very appreciated here

how about excluding directory, is there any work around?

thanks

Try this:

find ./files ! -path "*/warcraft*" \( -type d -o -name "*.abc" -o -name "*.txt" \) -print

thanks so much sir is working