Modify width of first column in file with a variable number of fields, using awk
You can use sprintf
to re-format $1
only.
Ex.
$ awk 'BEGIN{OFS=FS="|"} {$1 = sprintf("%-3s",$1)} 1' file
c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15
To figure out the largest/longest length of the first field, and then to reformat the values in the field according that length, you will have to do two separate passes over the file.
awk 'BEGIN { OFS = FS = "|" }
FNR == NR { if (m < (n=length($1))) m = n; next }
{ $1 = sprintf("%-*s", m, $1); print }' file file
(note that the input file is specified twice on the command line)
For the data that you present, this would produce
c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15
The first pass is handled by the FNR == NR
block, which simply keeps track of the longest field seen so far (m
contains the maximum length seen), and skips to the next line.
The second pass is handled by the last block, which reformats the first field using sprintf()
. The format string %-*s
means "a left-justified string whose width is given by the integer argument before the argument that holds the actual string".
This could obviously be expanded to do all columns by turning the scalar m
into an array that holds the maximum width of each column:
$ awk 'BEGIN { OFS = FS = "|" }
FNR == NR { for (i=1; i<=NF; ++i) if (m[i] < (n=length($i))) m[i] = n; next }
{ for (i=1; i<=NF; ++i) $i = sprintf("%-*s", m[i], $i); print }' file file
c1 |c2 |c3 |c4 |c5
c6 |c7 |c8 |c9 |c10
c11|c12|c13|c14|c15