Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

find string and print preceeding and following lines

Status
Not open for further replies.

rhnaeco

Technical User
Aug 11, 2005
45
hi, i have a data set of sonar pings. Each record consists of several lines of associate data such as depth and position and followed by 30 lines of actual data, followed by the next record.
normally i would say something like ' if $1 = "line1" then print next 30 lines' and then sort it out further from there.
In this case the only characters which consistantly appear are the letters BT on line 6, but i need info in the preceeding lines and followng lines; does anyone know how i would get awk to do this?:

find 'BT', print $2, $3, $4 of line -4 (line 2 for first record), print $1, $2 of line -2 (line 4)and print this as teh first 5 strings of every following data line (lines 7-30 for the first record), and then start again with the next instance of BT.

input (bracket numbers added for clarity):

1)485 1 0.900 -0.160 184.390 21.070
2)0.00 3.30 3.43 3.30
3)0.00 0.00 0.00 0.00
4)45.4257217 12.4309501 10.60
5)0.0 0.0 0.0 0.0
6)30 cm BT dB 0.43 0.156
7) 1.47 8.48 37.82 5.2 6.7 -8.6 -32768
8) 1.97 20.54 81.32 20.3 3.1 -7.1 -32768
9) 2.47 23.37 94.42 23.3 -1.8 -6.2 -32768
10) 2.97 12.82 3.58 0.8 12.8 -9.5 -32768

output:

1) 3.30 3.43 3.3 45.4257217 12.4309501 1.47 8.48 37.82 5.2 6.7 -8.6 -32768
2) 3.30 3.43 3.3 45.4257217 12.4309501 1.97 20.54 81.32 20.3 3.1 -7.1 -32768

hope this makes sense and really hope someone can help, or at least help to extract the lines which i need.

thanks in advance

rhnaeco
 
i can only see help for subsequent lines, not lines preceeding the label.....
 
Here's a solution using a buffer that holds the previous 5 lines:

Code:
awk '
    { buffer[NR%5]=$0 }
    /BT/ {
        split(buffer[(NR-4)%5],line2)
        split(buffer[(NR-2)%5],line4)
        for (i=7; i<=30; i++) {
            getline
            print line2[2],line2[3],line2[4],
                line4[1],line4[2],$1,$2,$3,$4,$5
        }
    }
'

Annihilannic.
 
thank you - it works great! I kind of understand how it works but i do have one question/confirmation - what does the '%' mean in this context- i thought it was to do with decimal places but the results show 7dp rather than 5. google deosn't really like '%' as a search and i can't say i understand the explanations in the man page.

thank you again for your help, it is very much apprieciated
 
% is the modulo operator.

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 
The modulo operator returns the remainder of a division, so the result of NR%5 will always be 0 - 4. It's a handy way to index a buffer like this because if you indexed it by record number or similar you would have to keep copying the data from the previous-previous line to the previous-previous-previons line, and previous line to the previous-previous line, and so on every time you read a line of data, if that makes sense.

Annihilannic.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top