Format output in columns

The answer by traybold using printf "%14s %14s %14s %14s %14s\n" $(cat data.txt) and should probably be used, but be aware that the last line is blank padded to full width. Also, if the data file is very big (256 KiB perhaps; almost certainly before you reach 1 MiB), you will run out of space for the command line arguments to printf. The solutions below will work with files that are many megabytes in size without adversely affecting the system.

You can almost use pr in multi-column mode (pr -5 -l1 -t), but it left-justifies the columns, so the - signs won't be presented correctly. OTOH, you could then feed the output into awk to do the right-justification:

pr -5 -l1 -t File | awk '{ printf "%14s %14s %14s %14s %14s\n", $1, $2, $3, $4, $5 }'

but if you're going to drag awk into the game, it can also do the 'transposition' for you — it just takes a bit more coding to do that, though.

Your suggestion almost works, but when I tried it, I get: 0.8725220D- 0.1609633D- 0.2598447D-; the exponent of each number is gone.

Some of the wonders of pr. By default, it uses tabs to separate columns. You can override that with -s' ' or by specifying that the output width is wider (e.g. -w100). Note that argument values such as the space need to be attached to the option, at least in traditional implementations of pr (but -w 100 works OK).

$ pr -s' ' -5 -l1 -t data | awk '{printf "%14s  %14s  %14s  %14s  %14s\n", $1, $2, $3, $4, $5}'
-0.3116274D-04  -0.2389361D-04  -0.1192458D-04   0.3306203D-04   0.2534987D-04
 0.1265136D-04  -0.2167920D-04  -0.3713258D-04  -0.2294900D-05  -0.4151710D-05
-0.7674479D-03  -0.5749288D-04   0.1393479D-04   0.6763913D-04   0.2515100D-05
-0.3638000D-06  -0.2630000D-06  -0.2445230D-06   0.1534680D-05   0.1579750D-04
 0.2922010D-04   0.5390530D-04   0.8701990D-04   0.1132741D-03   0.9665700D-04
 0.3337340D-04  -0.4121240D-05                                                
$ pr -w 100 -5 -l1 -t data | awk '{printf "%14s  %14s  %14s  %14s  %14s\n", $1, $2, $3, $4, $5}'
-0.3116274D-04  -0.2389361D-04  -0.1192458D-04   0.3306203D-04   0.2534987D-04
 0.1265136D-04  -0.2167920D-04  -0.3713258D-04  -0.2294900D-05  -0.4151710D-05
-0.7674479D-03  -0.5749288D-04   0.1393479D-04   0.6763913D-04   0.2515100D-05
-0.3638000D-06  -0.2630000D-06  -0.2445230D-06   0.1534680D-05   0.1579750D-04
 0.2922010D-04   0.5390530D-04   0.8701990D-04   0.1132741D-03   0.9665700D-04
 0.3337340D-04  -0.4121240D-05  
$

All these pr | awk solutions blank-pad the last line to full width.

Here are two equivalent awk scripts that do the job in one command. One spreads the code over 2 lines, the other over 16 lines (but it is easier to read):

Option 1:

awk '{ a[i++] = $0; if (i == 5) { printf "%14s  %14s  %14s  %14s  %14s\n", a[0], a[1], a[2], a[3], a[4]; i = 0; } }
     END { if (i > 0) { printf "%14s", a[0]; for (j = 1; j < i; j++) printf "  %14s", a[j]; printf "\n"; } }' data

Option 2:

awk '{  a[i++] = $0
        if (i == 5)
        {
            printf "%14s  %14s  %14s  %14s  %14s\n", a[0], a[1], a[2], a[3], a[4]
            i = 0
        }
     }
     END {
        if (i > 0)
        {
            printf "%14s", a[0]
            for (j = 1; j < i; j++)
                printf "  %14s", a[j]
            printf "\n"
        }
     }' data

The output is the same as before except that neither of these blank-pads the last line:

-0.3116274D-04  -0.2389361D-04  -0.1192458D-04   0.3306203D-04   0.2534987D-04
 0.1265136D-04  -0.2167920D-04  -0.3713258D-04  -0.2294900D-05  -0.4151710D-05
-0.7674479D-03  -0.5749288D-04   0.1393479D-04   0.6763913D-04   0.2515100D-05
-0.3638000D-06  -0.2630000D-06  -0.2445230D-06   0.1534680D-05   0.1579750D-04
 0.2922010D-04   0.5390530D-04   0.8701990D-04   0.1132741D-03   0.9665700D-04
 0.3337340D-04  -0.4121240D-05

It would be easier and shorter to write code that did; the reset code would also do delete a to clear the array and the END block would simply test i and use the printf from the main code:

awk '{  a[i++] = $0
        if (i == 5)
        {
            printf "%14s  %14s  %14s  %14s  %14s\n", a[0], a[1], a[2], a[3], a[4]
            i = 0
            delete a
        }
     }
     END {
        if (i > 0) printf "%14s  %14s  %14s  %14s  %14s\n", a[0], a[1], a[2], a[3], a[4]
     }' data

Try this:

printf "%14s  %14s  %14s  %14s  %14s\n" $(cat data.txt)

Tags:

Bash

Grep

Awk

Sed