Using Awk to process a file where each record has different fixed-width fields
Hopefully this will lead you in the right direction. Assuming your multi-line records are guaranteed to be terminated by a 'CC' type row you can pre-process your text file using simple if-then logic. I have presumed you require fields1,5 and 7 on one row and a sample awk script would be.
BEGIN { field1="" field5="" field7=""}{ record_type = substr($0,1,2) if (record_type == "AA") { field1=substr($0,3,6) } else if (record_type == "BB") { field5=substr($0,9,6) field7=substr($0,21,18) } else if (record_type == "CC") { print field1"|"field5"|"field7 }}
Create an awk script file called program.awk and pop that code into it. Execute the script using :
awk -f program.awk < my_multi_line_file.txt
You maybe can use two passes:
1step.awk
/^AA/{printf "2 6 6 12" }/^BB/{printf "2 6 6 6 18 6"}/^CC/{printf "2 8" }{printf "\n%s\n", $0}
2step.awk
NR%2 == 1 {FIELDWIDTHS=$0}NR%2 == 0 {print $2}
And then
awk -f 1step.awk sample | awk -f 2step.awk
You probably need to suppress (or at least ignore) awk
's built-in field separation code, and use a program along the lines of:
awk '/^AA/ { manually process record AA out of $0 } /^BB/ { manually process record BB out of $0 } /^CC/ { manually process record CC out of $0 }' file ...
The manual processing will be a bit fiddly - I suppose you'll need to use the substr
function to extract each field by position, so what I've got as one line per record type will be more like one line per field in each record type, plus the follow-on printing.
I do think you might be better off with Perl and its unpack
feature, but awk
can handle it too, albeit verbosely.