You can get the columns to line up, without using the column
command,
entirely within awk
, by doing
# fcinfo hba-port | awk '
BEGIN{man[-1]="HBA_Manufacturer"
ver[-1]="Firmware_Version"
sta[-1]="State"
man[0]="----------------"
ver[0]="----------------"
sta[0]="-----"
i=1
}
/Manufacturer:/ {man[i]=$2}
/Firmware Version:/ {ver[i]=$3}
/State:/ {sta[i]=$2; i++}
END {
maxlen1 = maxlen2 = maxlen3 = 0
for (j=-1; j<i; j++) {
if (length(man[j]) > maxlen1) maxlen1 = length(man[j])
if (length(ver[j]) > maxlen2) maxlen2 = length(ver[j])
if (length(sta[j]) > maxlen3) maxlen3 = length(sta[j])
}
for (j=-1; j<i; j++) {
printf("%-*s %-*s %-*s\n", maxlen1, man[j],
maxlen2, ver[j],
maxlen3, sta[j])
}
}'
This reads the entire input text, storing the data (including the headers)
in the man
, ver
, and sta
(manufacturer, version, and state) arrays.
The column headings are placed in the [-1]
entries, and the dashes
(which form a line between the headings and the data)
are placed in the [0]
entries;
these become the first two lines of the output (see below).
The actual data start at [1]
.
When it gets to the end of the data,
it determines the maximum length of the data (including the headings)
in each column, and then prints all the data (from the arrays),
using the calculated column widths.
printf("%16s", "Emulex")
prints Emulex
(ten initial blanks, followed by the six character name,
for a total of 16 characters).
printf("%-16s", "Emulex")
(note the -
) prints Emulex
(the six character name, followed by ten trailing blanks,
for a total of 16 characters).
printf("%-*s", 16, "Emulex")
does the same as
printf("%-16s", "Emulex")
,
except it gets the 16
from the argument list instead of the format string.
So the above will produce output like
HBA_Manufacturer Firmware_Version State
---------------- ---------------- -----
Emulex 2.82a4 online
Emulex 2.82a4 online
Emulex 2.82a4 offline
Emulex 2.82a4 offline
Emulex 2.82a4 online
Emulex 2.82a4 online
If you want more space between the columns,
add spaces to the printf
format.
For example, "%-*s %-*s %-*s\n"
would give you something closer to the example output you show.
The example output you show features a continuous row of dashes
after the headers. My command, as shown above,
will give only a short row of dashes under each header.
This becomes even more obvious if some of your data are longer:
HBA_Manufacturer Firmware_Version State
---------------- ---------------- -----
Emulex 2.82a4 online
Emulex 2.82a4 online
Some_other_manufacturer 2.82a4 offline
Emulex 2.82a4 offline
Emulex 2.82a4 online
Emulex 2.82a4 online
This can be fixed, if necessary.
- This may fail if your input data are huge,
because
awk
might run out of space to hold all the data.
- This might fail with a syntax error
if you have an older version of
awk
(e.g., on Solaris).
If that happens, try putting the printf
statement all on one line, as
printf("%-*s %-*s %-*s\n", maxlen1, man[j], maxlen2, ver[j], maxlen3, sta[j])
– krock1516 Mar 02 '16 at 08:04awk: syntax error near line 22 awk: illegal statement near line 22 awk: syntax error near line 23 awk: illegal statement near line 23
awk
that Linux/GNU systems do. Try putting theprintf
statement all on one line, asprintf("%-*s %-*s %-*s\n", maxlen[1], man[j], maxlen[2], ver[j], maxlen[3], sta[j])
. – G-Man Says 'Reinstate Monica' Mar 02 '16 at 08:09You are the Man , Cheers!
– krock1516 Mar 02 '16 at 08:26man[-1] & man[0]
arrays in the code? – krock1516 Mar 03 '16 at 07:56