#!/usr/bin/awk -f # Pretty Print a table encoded as tab-separated values. # Pad each left justified field with enough spaces on the right # to make the columns line up. # Put two spaces between the columns. # If you define HEADERS to be a comma separated list of column headings, # They will appear underlined before the data. # This will look like text dumps from some data base software (e.g. DB2). # e.g. tsv2txt.awk HEADERS=ONE,TWO,THREE BEGIN { FS = "\t"; HEADERS = ""; } { line[NR] = $0; if ( longest < NF ) { longest = NF; } for ( i = 1; i <= NF; i++ ) { w = width[i]; if ( w < length( $i ) ) { width[i] = length($i); } } } # return the character (or string) c repeated n times. # Note that i and answer are not real parameters. # They are local variables. function chars( n, c , i, answer ) { answer = ""; for ( i = 0; i < n; i++ ) { answer = answer c; } return answer; } END { n = split( HEADERS, head, /, */ ); if ( 0 < n ) { # headers were specified. if ( longest < n ) longest = n; # Print the column headings. printf( "%-" width[1] "s", head[1] ); if ( width[1] < length( head[1] ) ) width[1] = length( head[1] ); for ( i = 2; i <=n; i++ ) { printf( " %-" width[i] "s", head[i] ); if ( width[i] < length( head[i] ) ) width[i] = length( head[i] ); } printf "\n"; # Print a dashed line to separate the column headings # from the data. printf( "%-" width[1] "s", chars( width[1], "-" ) ); for ( i = 2; i <= longest; i++ ) { printf( " %-" width[i] "s", chars( width[i], "-" ) ); } printf "\n"; } for ( i = 1; i <= NR; i++ ) { n = split( line[i], a ); if ( 0 < n ) { printf( "%-" width[1] "s", a[1] ); for ( j = 2; j <= n; j++ ) { printf( " %-" width[j] "s", a[j] ); } } printf "\n"; } }