How can I print values from a data file after a specific pattern is found, and one line skipped in between?
The following awk
program should do the job:
awk 'BEGIN{n=-1}
n>0{printf "S%-*d=%s\n",w,++i,$6; if (i==n) {i=0;n=-1}}
n==0{n=$1;w=length($1)}
$0=="DATA_POINTS"{n=0}' file
This will:
- At the beginning, initialize a "status flag"
n
with-1
, meaning "outside the data block". - When a line consisting only of the string
DATA_POINTS
is encountered, setn
to0
, meaning "the next line contains the number of data points" - When
n
is zero, the content of the line is interpreted as number of data points and stored inn
. The length of that number (in characters/digits) is stored in a fieldw
used for formatting the output later. - When
n
is larger than0
, indicating we are inside the "data" block, print the "key" with the counting variablei
(formatted for fixed width usingw
and left-adjusted as in your output example) and the 6th field of the line, untili
is equal ton
, at which pointn
is reset to-1
This has probably more functionality than you need to, in that it can handle data blocks which are not located at the end of the file (it respects the number of data lines specified in the header, rather than reading just until end-of-file).
Note that the method for finding DATA_POINTS
is currently full string matching, which is the most robust method if the actual string can contain special characters. If you want partial string matching, or regular expression matching, use either
index($0,"DATA_POINTS") { ... }
or (as in your example)
/DATA_POINTS/ { ... }
In addition, if you want to guard against misinterpreting empty lines, replace n>0
and n==0
with n>0&&NF
and n==0&&NF
, respectively.
Make use of the range operator ,
. Start is the data points line and end is eof.
awk '
/DATA_POINTS/,0 {
if ( /DATA_POINTS/ ) {
getline; next
}
printf "S%-2d=%s%s\n", ++k, OFS, $6
}
' file
$ awk '/DATA_POINTS/{c=3} c&&!--c{f=1} f{printf "S%d = %s\n", ++s, $6}' file
S1 = A
S2 = B
S3 = C
S4 = D
S5 = E
S6 = F
S7 = U
S8 = W
S9 = L
S10 = K
S11 = U
S12 = X
To start printing from the 27th line from the matching line (inclusive) instead of the 3rd, just change 3 to 27.
See https://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern/17914105#17914105 for more information on the above approach and more ways to do something after a match.