Stack Exchange
AWK printing fields in multiline records
I have an input file with fields in several lines. In this file, the field pattern is repeated according to query size.
ZZZZ
21293

YYYYY     XXX     WWWW   VV
13242     MUTUAL  BOTH   NO

UUUUU   TTTTTTTT  SSSSSSSS   RRRRR   QQQQQQQQ  PPPPPPPP
 3       0                    3       0

NNNNNN  MMMMMMMMM  LLLLLLLLL  KKKKKKKK  JJJJJJJJ
 2       0                     5         3

IIIIII  HHHHHH  GGGGGGG  FFFFFFF  EEEEEEEEEEE  DDDDDDDDDDD
 5       3       0                 3           

My desired output is one line per total group of fields. Empty 
fields should be marked. Example:"x"
21293 13242 MUTUAL BOTH NO 3 0 X 3 0 X 2 0 X 5 3 5 3 0 X 3 X
12345 67890 MUTUAL BOTH NO 3 0 X 3 0 X 2 0 X 5 3 5 3 0 X 3 X  

I have been thinking about how can I get the desired output with awk/unix scripts but can't figure it out. Any ideas? Thank you very much!!!

Where are 12345 and 67890 in the input?

So your fields in the second line of each pair are based on column positions from the XXXX things in the first line?

Shouldn't XXX be XXXXXX so it's as long as the value below it?

There isn't going to be an easy way to detect that the 'S' field doesn't have a value in the following line.  Superficially, the 'P' field is easier, at least if none of the earlier fields is missing.  (The 'L', 'F' and 'D' fields will be similarly fun, of course.) Are the blank lines in the data?   The output starting 12345 isn't illustrated from the input data.  How do you know when you're starting a new block of data?  How well aligned is the second (data) line with the prior (mask) line?  Are you sure you can't get the data presented in a more readily processed format?

Why does the output end with 5 3 0 X X? Shouldn't it be 5 3 0 X 3 X?

You haven't told us how fields are separated yet. Is it sequences of space characters or tabs or something else?

My inputs are all the lines shown with field names "ZZZZ" to "DDDDDDDDDD". Fields in second line seems to be based on column position but I wouldn´t count on that. Field name length is a fixed value per field. It is not related to value length. My original file has blank lines. My fields are separated by whitespaces one or more.

@Barmar you are correct about your output comment. Sorry, my mistake.I have to mark every empty field because I need to process the output knowing if a field is empty or not

This isn't really a great fit for awk's style of programming, which is based on fields that are delimited by a pattern, not fields with variable positions on the line. But it can be done.
When you process the first line in each pair, scan through it finding the positions of the beginning of each field name.
awk 'NR%3 == 1 {
        delete fieldpos;
        delete fieldlen;
        lastspace = 1;
        fieldindex = 0;
        for (i = 1; i <= length(); i++) {
            if (substr($0, i, 1) != " ") {
                if (lastspace) {
                    fieldpos[fieldindex] = i;
                    if (fieldindex > 0) {
                        fieldlen[fieldindex-1] = i - fieldpos[fieldindex-1];
                    }
                    fieldindex++;
                }
                lastspace = 0;
            } else {
                lastspace = 1;
            }
        }
    }
    NR%3 == 2 {
        for (i = 0; i < fieldindex; i++) {
            if (i in fieldlen) {
                f = substr($0, fieldpos[i], fieldlen[i]);
            } else { # last field, go to end of line
                f = substr($0, fieldpos[i]);
            }
            gsub(/^ +| +$/, "", f); # trim surrounding spaces
            if (f == "") { f = "X" }
            printf("%s ", f);
        }
    }
    NR%15 == 14 { print "" } # print newline after 5 data blocks
'


Thanks again Barmar for your answer. What other programming language is best suited to deal with this input? What would you recommend?

Perl might be better. The main thing you want is a function that allows you to search a string for the position of the first space or non-space character, so you don't have to loop character by character like I did.

Assuming your fields are separated by blank chars and not tabs, GNU awk's FIELDWITDHS is designed to handle this sort of situation:
/^ZZZZ/ { if (rec!="") print rec; rec="" }
/^[[:upper:]]/ {
    FIELDWIDTHS = ""
    while ( match($0,/\S+\s*/) ) {
        FIELDWIDTHS = (FIELDWIDTHS ? FIELDWIDTHS " " : "") RLENGTH
        $0 = substr($0,RLENGTH+1)
    }
    next
}
NF {
    for (i=1;i<=NF;i++) {
        gsub(/^\s+|\s+$/,"",$i)
        $i = ($i=="" ? "X" : $i)
    }
    rec = (rec=="" ? "" : rec " ") $0
}
END { print rec }

$ awk -f tst.awk file
2129 13242 MUTUAL BOTH NO 3 0 X 3 0 X 2 0 X 5 3 5 3 0 X 3 X

In other awks you'd use match()/substr(). Note that the above isn't perfect in that it truncates a char off 21293 - that's because I'm not convinced your input file is accurate and if it is you haven't told us why that number is longer than the string on the preceding line or how to deal with that.
