0

I have no experience with awk, sed, grep and etc. Trying to phrase my question makes it seem more confusing than it should so I will start with an example of what I am trying to achieve.

input1

A B C D  
A B C  
A B C D E F  

input2

v A  
c B  
c C  
c D  
v E  

output

A B C D  
v c c c  
A B C  
v c c  
A B C D E F  
v c c c v Ø

so basically I have 2 input files.

input1 where each line has a different number of fields.
input2 where every line has 2 fields.

I need an output where for each line in input1 it will first print the full line with all its fields, then for the following line of output, it will lookup the content of each field of that line from input1 in the second field of input2. Then print the first field of that line from input2, or an Ø in case that content is not found in input2. Repeat that until the last field, printing the results in a single line. Then do the same for each line in input1.

As I will be doing slightly different tasks like this, a brief explanation of what each part of the commands does would be highly appreciated. Thanks in advance.

0
$ awk 'FNR == NR {   a[$2] = $1; next }
                 {   print
                     line = (a[$1] ? a[$1] : "Ø")
                     for (i = 2; i <= NF; ++i) {
                        line = line OFS (a[$i] ? a[$i] : "Ø")
                     }
                     printf("%s\n", line)
                 }' input2 input1
A B C D
v c c c
A B C
v c c
A B C D E F
v c c c v Ø

That is, if we're reading from the first file (input2), populate a lookup table with what symbols each character should be replaced with.

When reading the second file (input1), output the input line, then loop through the fields and construct a string with the correct symbols from the lookup table. If a symbol is missing from the lookup table, insert Ø.

Then output the assembled string with a terminating newline.


You may also turn it into a proper script:

#!/usr/bin/awk -f

FNR == NR {   a[$2] = $1; next }
          {   print
              line = (a[$1] ? a[$1] : "Ø")
              for (i = 2; i <= NF; ++i) {
                  line = line OFS (a[$i] ? a[$i] : "Ø")
               }
                     printf("%s\n", line)
          }

Then make it executable (chmod +x script) and run it like so:

$ ./script input2 input1
A B C D
v c c c
A B C
v c c
A B C D E F
v c c c v Ø
  • when I use this with the example files all fields except for the last one are being printed as Ø – z3itg3istc4tchup Sep 12 '17 at 19:44
  • @z3itg3istc4tchup Did you copy-and-paste or re-type? I've made sure this works with three different implementations of awk on the data that you provided. Make sure to give the input files in the correct order, input2 first. – Kusalananda Sep 12 '17 at 19:47
  • copy-and-paste, checked and double checked, I am not sure what is going wrong – z3itg3istc4tchup Sep 12 '17 at 19:51
  • @z3itg3istc4tchup I updated the answer with another way of running it. If that also fails, then there may be some issue with your input files (like having DOS line-endings). – Kusalananda Sep 12 '17 at 19:57
  • 1
    DOS line-endings, that was it. all working now, thank you :) – z3itg3istc4tchup Sep 12 '17 at 20:08
0

This appears to work:

awk 'NR==FNR { code[$2]=$1 } NR!=FNR {print; for( i=0; i<=NF; i++) { printf( "%s ", code[$i] ) }; printf "\n" }' input2 input1

The NR==FNR block runs only on the first file specified (wherein the number of records processed in total is equal to the total number overall thus far), and populates an array used for the output later.

The NR!=FNR block runs only on the subsequent file, and first outputs the given line of input, and then steps through it and uses each value as the subscript of an array lookup to determine whether to output v or c.

After this iterated series, a newline is output.

  • the output won't show most values in the even lines – z3itg3istc4tchup Sep 12 '17 at 19:55
  • oops, it turns out the problem was with my input files – z3itg3istc4tchup Sep 12 '17 at 20:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.