Column formatting unix
awk
to the rescue!
I'll solve the name problem for you in a different way and show how to use printf for formatting, you can add the headers and rest of fields looking up the answer above.
$ awk 'NF==9{for(i=NF;i>=4;i--) $(i+1)=$i; $4=""} {printf "%d %-15s %5s\n", $1,$2" "$3" "$4, $5}' file1 Jackson, Bob D. C00012 Filer, Jack C00023 Metro, Jim K. C0003
I would not bother figuring out how many names the person has. You know the last 6 fields are the "values", and the first field is the number, and whatever's left are the names. The index arithmetic is a bit tricky but not too bad:
awk ' # too bad awk doesn't have a built-in join function function join(sepstr, array, len, sep, i, result) { sep = "" result = "" for (i=1; i <= len; i++) { result = result sep array[i] sep = sepstr } return result } BEGIN {print "#:Name:LS:mode:food:item:num:list"} { delete result result[1] = $1 for (i=1; i <= 6; i++) result[i+2] = $(NF-6+i) delete names len=0 for (i=2; i <= NF-6; i++) {names[i-1] = $i; len++} result[2] = join(" ", names, len) print join(":", result, 8) }' file | column -t -s:
# Name LS mode food item num list1 Jackson, Bob D. C0001 book pizza apple 4.00 123as2 Filer, Jack C0002 happy apple hat 4.00 124ab3 Metro, Jim K. C0003 kindle pizza grape 4.00 125ac
If you really need the separator, pipe the column
output into
perl -lpe 'if ($. == 2) {($line=$_) =~ s/(\S+.*?)($| (?=\S))/ "-" x length($1) . $2 /ge; print $line}'
to get
# Name LS mode food item num list- --------------- ----- ------ ----- ----- ---- -----1 Jackson, Bob D. C0001 book pizza apple 4.00 123as2 Filer, Jack C0002 happy apple hat 4.00 124ab3 Metro, Jim K. C0003 kindle pizza grape 4.00 125ac
Note, if you're not tied to awk, perl is much more concise. Perl's array manipulation functions far out-strip awk. As shown below we have shift
/unshift
which remove/add elements from the front of a list, and pop
/push
which remove/add elements from the end of a list:
perl -lane ' BEGIN {print "#:Name:LS:mode:food:item:num:list"} undef @res; unshift @res, pop @F for 1..6; $n = shift @F; unshift @res, $n, join(" ", @F); print join(":", @res)' file | column -t -s:
printf
is your friend.
example
awk '{ printf "%-30s %s \n", $1, $2 }' inputfile.txt
In the above example, first column will be 30 characters left justified.
awk printf
supported datatypes
%i or d --Decimal%o --Octal%x --hex%c --ASCII number character%s --String%f --floating number
Padding options
-n --Pad n spaces on right hand side of a column.n --Pad n spaces on left hand side of a column..m --Add zeros on left side.-n.m --Pad n spaces right hand side and add m zeros before that number.n.m --Pad n spaces left hand side and add m zeros before that.
Using above details, we can rewrite awk
statement like this
awk 'BEGIN { format = "%d %-15s %5s %-9s %-5s %-5s %1.2d %5s \n" printf format, "#", "Name", "LS", "mode","food","item","num ","list" printf format, "-","---------------","-----","---------","-----","-----","----","-----" } { printf format, $1, $2, $3, $4, $5, $6, $7,$8 }' inputfile.txt
perl solution
$ perl -lane 'printf "%d%-15s%5s%-9s%-5s%-5s%-5s%1.2d%5s\n",@F' file