Awk {print} -in the order I determine

Hello everyone! In a shell script I read an input file, from which I want to print on an output file strings from different lines. I set as a landmark a line that start with the word ''DATA''. Now I want to print, on the output file:

  • FIRST a string 3 lines below my landmark line
  • SECOND a string 6 lines bellow my landmark line
  • LAST a string in the same line.
    My problem is the output file doesn't follow the print order I determine, but print first the string that comes first in the imput file (= ^DATA/ {print $3,$4} ). How can I fix it?
awk '/^DATA/ { matrix1[NR+3] } ;NR in matrix1 { printf " %5s",  $2 } ; /^DATA/{ matrix2[NR+8] } ; NR in matrix2 { printf "%6.1f", $2 } ; /^DATA/ {print  $3,$4}' $inputfile | sort -n >> $outputfile

Thank you very much!

Welcome to the community!

Either save the previous printouts in variables, and print them together with the last one.
Or read-ahead the next lines with getline().

The "save" method:

awk '/^DATA/ { nr=NR; sav1=($3 OFS $4) } ; NR == nr+3 { sav2=$2 } ; NR == nr+6 { printf "%6.1f %5s %s\n", $2, sav2, sav1 }' $inputfile
2 Likes

@ChaosTheory,
it would help you and all of us if could provide a small representative sample of the input file AND the matching desired output. Otherwise we're (all) simply guessing what you're striving to achieve.

E.g. are the 3rd/6th lines after the "marker" line simply determined by their line numbered location OR they have some other "designation" (e.g. a certain string distinguishing them from the other lines?

Looking at a sample representative file (potentially covering edge cases) could demonstrate what you're after.

You are right , I am sorry.
Here is a sample of the input file

SEISMIC CATALOGUE
DATA 2000 CALIFORNIA USA
STATION CAL1
   Date       Time       Err   ....
2000/05/01 00:02:45.1    0.43  

Magnitude  Err ....
M      5.2  0.6...

And what I want to print at the output file is

    Date               Time    Magnitude  Region
2000/05/01 00:02:45.1  5.2       CALIFORNIA USA

Hope it will help

@ChaosTheory , I've edited your data sample using the proper markdown formatting for now.
Please make sure you format your data/code sample yourself going forward,

Please make sure you provide the exact as you have it - don't post partial data with ...-s.
I've guessed the best I could what I'd thought your data looked like.

Given the provided/edited/formatted data input and the suggestion by @MadeInGermany:

awk '/^DATA/ { nr=NR; sav1=($3 OFS $4) } ; NR == nr+3 { sav2=$2 } ; NR == nr+6 { printf "%6.1f %5s %s\n", $2, sav2, sav1 }' myInputFile

yields:

   5.2 00:02:45.1 CALIFORNIA USA

Looks like your provided sample input doesn't exactly jive with your original description.

Furthermore, I'd suggest providing more sample data potentially resulting in more than ONE output record.

2 Likes

In a BEGIN section, and by defining a format in a variable with only %s elements, you can automatically align a header line.
Non-%s elements you can preformat with sprintf()

awk 'BEGIN { pform="%10s %10s  %-9s  %s\n"; printf pform, "D
ate", "Time", "Magnitude", "Region" } /^DATA/ { nr=NR; sav1=($3 OFS $4) } NR ==
nr+3 { sav2=$1; sav3=$2 } nr && NR == nr+6 { printf pform, sav2, sav3, sprintf("
%-5.1f", $2), sav1 }' $inputfile

For fun, here is the answer provided by ChatGPT:

It looks like you are using awk to parse and process your input file, and you want to store some information in arrays matrix1 and matrix2, then print them out to the output file in a specific order. However, it seems that the order in which the information is printed to the output file is not the same as the order you specified.

To fix this issue, you can try modifying your awk script as follows:

  1. Instead of storing the information you want to print in arrays matrix1 and matrix2, you can store them in separate variables, for example string1, string2, and string3.
/^DATA/ { string1 = $2 }
/^DATA/ { string2 = $2 }
/^DATA/ { string3 = $3 " " $4 }
  1. After you have read and stored all the necessary information from the input file, you can print the variables in the desired order by using a single print statement.
END {
    print string1
    print string2
    print string3
}

This should ensure that the strings are printed in the correct order in the output file.

I hope this helps! Let me know if you have any questions.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.