awk

How to get strings within square brackets [] in the declarations line and their related import strings


In a text file which has the line beginning with the "declarations:" string, replace "declarations" with "imports", replace "AppComponent" or "NxWelcomeComponent" with "", parse the result string to get the individual string separated by comma ",", and get their related import strings from above. e.g. in:

import { RouterModule } from '@angular/router';
import { ScrollDirective } from './directives/scroll.directive';
import { TestComponent } from './test';
import { Test2 } from './test2';
import { Test3 } from './test';

@NgModule({
  declarations: [AppComponent, NxWelcomeComponent, ScrollDirective, TestComponent, Test2],
})

Expected out:

import { ScrollDirective } from './directives/scroll.directive';
import { TestComponent } from './test';
import { Test2 } from './test2';

imports: [ScrollDirective, TestComponent, Test2],

I tried: test.awk:

/declarations:/ {str=$0;  sub("declarations", "imports", str) ; sub("AppComponent,", "", str) ; sub("NxWelcomeComponent,", "", str) }
/import/ { importbuf[++arrindex]=$0}

END {
    for (i in importbuf) {
        print importbuf[i]
    }
    print str
}
awk -f test.awk in

Extra input in2:

import { RouterModule } from '@angular/router';
import { ScrollDirective } from './directives/scroll.directive';
import { TestComponent } from './test';
import {Test4} from './test4';

@NgModule({
  declarations: [AppComponent, NxWelcomeComponent, ScrollDirective, TestComponent, Test4],
})

Expected out2:

import { ScrollDirective } from './directives/scroll.directive';
import { TestComponent } from './test';
import {Test4} from './test4';

imports: [ScrollDirective, TestComponent, Test4],
awk -f test.awk in2

Solution

  • You may use this 2 pass awk solution.

    cat imports.awk
    
    NR == FNR {
       if ($1 ~ /^declarations/) {
          gsub(/[[:blank:]]*declarations[^[]*\[|].*/, "")
          n = split($0, tok, /[[:blank:]]*,[[:blank:]]*/)
          for (i=1; i<=n; ++i)
             imports[tok[i]]
       }
       next
    }
    /^[[:blank:]]*import/ {
       s = $0
       gsub(/^[[:blank:]]*import[^{]*{ *| *}.*/, "")
       if ($0 in imports) {
          print s
          pimports[++k] = $0
       }
    }
    
    END {
       printf "\nimports: ["
       for (i=1; i<=k; ++i)
          printf "%s", (i>1 ? ", " : "") pimports[i]
       print "],"
    }
    

    Then use it as:

    awk -f imports.awk in in
    
    import { ScrollDirective } from './directives/scroll.directive';
    import { TestComponent } from './test';
    import { Test2 } from './test2';
    
    imports: [ScrollDirective, TestComponent, Test2],
    

    Or for the 2nd example:

    awk -f imports.awk in2 in2
    
    import { ScrollDirective } from './directives/scroll.directive';
    import { TestComponent } from './test';
    import {Test4} from './test4';
    
    imports: [ScrollDirective, TestComponent, Test4],