Create lists of words according to binary numbers

In awk:

NR == 1 { for(column=1; column <= NF; column++) values[column]=$column; }
NR > 1 { output=""
        for(column=1; column <= NF; column++)
                if($column) output=output ? output "," values[column] : values[column]
        print output }

Another one with perl

$ perl -lane 'if($. == 1){ @h=@F }
              else{@i = grep {$F[$_]==1} (0..$#F); print join ",",@h[@i]}
             ' ip.txt
E,I
D
D
A
A,C,G
A,D,H
A,E,F,G
  • -a option to split input line on white-spaces, available in @F array
  • if($. == 1){ @h=@F } save the header if first line
  • @i = grep {$F[$_]==1} (0..$#F) save index if entry is 1
  • print join ",",@h[@i] print only those index from header array using , as separator

Still for the fun of it, a zsh version:

{
   read -A a  &&
   while read -A b; do
     echo ${(j<,>)${(s<>)${(j<>)a:^b}//(?0|1)}}
   done
} < file
  • ${a:^b} zips the two arrays, so you get A 0 B 0 C 0 D 0 E 1 F 0 G 0 H 0 I 1
  • ${(j<>)...} joins the elements with nothing in between so it becomes A0B0C0D0E1F0G0H0I1
  • ${...//(?0|1)} we strip the ?0 and 1 from it so it becomes EI:
  • ${(s<>)...} split on nothing to get an array of one element per letter: E I
  • ${(j<,>)...} join those with , -> E,I.